Hi, 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: void 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 later. Bye, Henning