[sane-devel] Interactive use of scanner buttons
Ralph Little
skelband at gmail.com
Thu Dec 9 00:16:37 GMT 2021
Hi,
As an aside, some discussion around this was had before. There is an issue
in the SANE standard repo where we might decide on something:
https://gitlab.com/sane-project/standard/-/issues/7
Cheers,
Ralph
On Wed, Dec 8, 2021 at 10:23 AM Paul Wolneykien <manowar at altlinux.org>
wrote:
> 3 декабря 2021 г. 19:00:25 GMT+03:00, Paul Wolneykien
> <manowar at altlinux.org> пишет:
> >В Fri, 03 Dec 2021 10:34:05 -0500
> >ryniker at ryniker.org пишет:
> >> A callback mechanism provides a framework that can naturally avoid
> >> missed button events, and can support variations such as capture of
> >> "button down" and "button release" events without a requirement for
> >> the program with physical access to the hardware to maintain state
> >> information until a suitable poll operation is received.
> >>
> >> A callback design is better able to support multiple
> >> buttons. Applications have less need for complex polling operations
> >> (three buttons... which was pressed first?)
> >
> > Then, I'll try to experiment this way with my scanner.
>
> I think we have a problem with concurrent SANE access.
>
> First of all, the USB abstraction in SANE seems to be thread unsafe:
> at least the USB read timeout is set separately from read with
> sanei_usb_set_timeout() while the actual reading is done with
> sanei_usb_read_*(). With libusb_timeout being a global variable in
> sanei_usb.c I don't understand is it possible to work even with two
> different devices (scanners) from the same app in parallel?
>
> And what about concurrent calls to sane_control_option(),
> sane_start() related to the same device from the same app?
> It might be possible to synchronize (enqueue) these calls with
> saned daemon, but in the simplest local-running case they seem to be
> unsynchronized... Is that true?
>
> Secondly. With the notification callback scheme we've discussed
> earlier (above), it's important not to make the notification calls come
> from "nowhere" (a separate thread spawned in the backend). That was
> really wrong. The scanning application should explicitly maintain all
> the threads that can call its own functions. And there is a known
> solution to this problem in libusb: the libusb_handle_events*() set of
> functions. However, this approach is really a lighter version of
> polling: a polling of the internal state without sending any packets
> over USB. We can call this a "software polling" meaning no regular
> signals are sent over the wire.
>
> So, if we would even try to add a sane_handle_events() in SANE it
> would still be a polling solution, a solution requiring polling
> procedure in a single-threaded frontend as we can't safely access two
> USB endpoints in parallel with SANE.
>
> Then, a question arise: can we get a software polling with the
> present SANE API? And again I think we can.
>
> With adding the new option capability
>
> + #define SANE_CAP_EVENT
>
> we can mark options which state is safe to be asked as frequently as
> you want. Technically this can be achieved by using
> sanei_usb_read_int() on scanners with interrupt endpoint for buttons:
> that function doesn't sent anything to the device but just checks the
> state of the internal queue for the presence of any already received
> data (that is pushed by the scanner to the PC).
>
> Moreover, reading a SANE_CAP_EVENT option shouldn't just return a
> "now" value --- it should return the next available value from the
> event queue, as a number of events could have been received by the
> time of the read. It should not be "the button is down (up) now at
> the moment you ask" as it is now with button options.
>
> Having an event queue is the useful approach to work with events,
> but only if you have a way to reset the queue and start over: i. e. if
> you can throw away meaningless events from the past. And that's also
> can be naturally done with the present API: invocation of
> SANE_ACTION_SET_VALUE against the event option should do the trick.
>
> What about the network (remote scanner) case? I think, that in that
> case, a regular polling of SANE_CAP_EVENT options can be done by saned
> daemon itself, with some reasonable (and configured) period. In order
> to keep it single-threaded the daemon should stop this polling on
> reception of a command from the remote frontend (and then, to start it
> over being idle again). Then, in the case of an event being read the
> daemon should immediately pass it further to the frontend's network
> client part, where it should be appended to the internal queue. The
> frontend polling procedure would work with that queue under the hood
> and wouldn't pollute the network with "read-read-read" commands.
>
> Actually, the network pollution is still possible with that scheme
> but only with the packets coming from (!) the remote scanner to PC ---
> from some mad scanner that is trying to DDoS us! :-)
>
> Any comments about this update?
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/sane-devel/attachments/20211208/a822ae36/attachment.htm>
More information about the sane-devel
mailing list