[sane-devel] SANE V2
Tue, 10 Dec 2002 11:06:33 +0100
On Mon, Dec 09, 2002 at 04:39:54PM -0500, Matto Marjanovic wrote:
> (For those who've lost track: "this method" is to use struct, containing
> both the status code and a verbose string pointer, as the return value of
> all the sane_() functions.)
> Um, except now a string has to be marshalled over the network every time
> a sane function is called, and reconstructed on the client side even if
> it isn't used.
And after every call to an SANE function, it must be checked for NULL
and otherwise freed. No, I don't think that's the way to go.
> >> Yet another way would be to use an additional callback:
> >Callbacks always give me nightmares (I'm developing a db async access
> >infrastructure that interacts with gtk... brr!)
> A true asynchronous callback cannot be used with the network protocol.
> However, it can work in this case:
> o Frontend calls sane_func(), hands its callback to network backend.
> o Net backend signals remote net frontend "execute sane_func()".
> o Remote network frontend calls sane_func(), hands its callback to backend.
> o Backend calls network callback to put a string somewhere on remote side.
> o Remote network frontend sends that string back along with the response
> to "sane_func()" request.
If I understand correctly what happens in the case of auth_callback,
the remote sane_func isn't finished yet, the callback is still running.
> o Network backend calls the client frontend's callback with string,
> then finally returns from "sane_func()" request.
First the net backend calls the RPC for sane_func again, saned returns
from the clalbach, the remote frontend returns from sane_func() and
give the result back all the way to the local frontend.
> But this has pretty much all the same problems and lack of benefits as
> the above method.
And it's pretty much complictated and means that we need to add
another parameter for each RPC that may return an error status.
> I much prefer Henning's original idea, as follows:
> Threading is not a very big issue for SANE.
> >From the perspective of a single device handle, most of the API is
> synchronous and leaves no room for threading anyway --- except for
> That is to say, I am not allowed to call a second sane_func(H, ...) on the
> same device handle H while another sane_func(H, ...) is still executing.
> (Except for sane_cancel() --- I had some remarks about this a while ago,
> too; I'll try to find them.)
> That means that the current error state, per device handle, is well-defined
> at all times. So, I don't see any problems with Henning's original idea:
> >> > SANE_String_Const sane_verbose_error(Sane_Handle h)
> >> >
> >"This function provides a verbose description of the error code
> >returned by the latest call to a SANE function. The returned ...
> >So the intention is: the message stays the same until any other
> >SANE function returns an non-error status code. Everything not
> >returning a status would be ignored.
> This function always provides the error "when the error occurs", because
> it is called after one sane_func(H) and before the next sane_func(H).
> The string pointer returned by this function should be valid until the
> next sane_function(H) is called on the same device handle. This is
> important to maintain thread-safety over multiple devices.
> The string is, however, "owned" by the backend, which is free to overwrite
> it, free() it, etc., during the next sane_func(H) call.
> The backend can allocate/write this string anyway it wants, and no one
> else has to deal with it until the frontend explicitly asks for it.
As far as I understood the comment about thread-safety (from David
Mosberger-Tang) is about interface definition, not implementation.
So even if the current implementation doesn't allow simuktaneous
operation of SANE function, a later one may do. And we are in trouble
then. All the other function definitions seem to be thread-safe.
So I guess the following won't hurt:
sane_verbose_error(Sane_Handle h, SANE_String * verbose_message, SANE_Int lenght)
The the frontend can decide what to do with the string, e.g. print it