[sane-devel] SANE V2

Henning Meier-Geinitz henning@meier-geinitz.de
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
>  sane_canel().
> 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