[sane-devel] SANE V2
Mon, 9 Dec 2002 16:39:54 -0500
>From: Diego Zuccato <firstname.lastname@example.org>
>Date: Mon, 09 Dec 2002 00:13:01 +0000
>Henning Meier-Geinitz wrote:
>> And this would be returned by any SANE API function that currently
>> returns SANE_Status? Nice, because it links the error number and the
>> message. No need for an extra call to a function.
>Yep. That's why I like this method. :-)
(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.
>> 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.
o Network backend calls the client frontend's callback with string,
then finally returns from "sane_func()" request.
But this has pretty much all the same problems and lack of benefits as
the above method.
>> The really interesting error messages are the dynamic ones: "Couldn't
>> open %s". And %s can be anything and can change multiple times between
>> sane_init and sane_exit.
>Err... I didn't think about these. :-(
>Well, in that case, use the strdup() technique: the called function
>allocates the needed memory that must be freed by the caller. I heard
>(well, seen in some code) that that could be a problem under winkozz,
>since if a dll allocates memory, that memory must be freed from the dll
>itself. Just add a free() wrapper in the dll code... May be SANE_free()
What a pain....
Now I have to call some version of free() (either SANE's or just libc's)
everytime I call a sane_function()!!!
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.
-matt "keepin' it real (simple)" m.