[sane-devel] Proposal: SANE standard additions/fixes
Henning Meier-Geinitz
henning@meier-geinitz.de
Thu, 10 Oct 2002 18:07:14 +0200
Hi,
On Sun, Oct 06, 2002 at 01:01:52PM -0400, Matto Marjanovic wrote:
> >2) Concerning sane_get_select_fd: It's not that easy to implement the
> > select fd correctly in frontends and backends. For frontends the
> > problem is, that not only the readable status has to be cheked but
> > also if the fd was closed. E.g. using a gdk_input will not work
> > because it won't detect the closing of the file descriptor by the
> > backend and waits forever.
> >
> > So if you use select you have to check the return value of select
> > if the fd was closed (that means EOF in the next call to SANE_READ)
> > and so you can call sane_cancel. If no error occured, check if the
> > fd is readable. If yes, run sane_read, otherwise wait.
> >
> > Maybe we can add a "frontend implementation note" for that one.
> > I don't know how to write this exactly, maybe Oliver?
>
> Well, I was the guy who thought it might be a good idea to get rid of this
> mode of operation altogether, so I'm not the best one to comment. (Feel
> free to skip ahead; somehow it turned into thoughts on the semantics of
> sane_cancel(), until (e) and (f)....)
I'm also not sure if that mode is really necessary but changing that
is for SANE2. Maybe it makes sense for networking/saned?
> The standard does seem to be unclear on what happens when sane_cancel()
> is called:
>
> a) If you are in the middle of another sane call, and sane_cancel() is
> called (via a signal handler), the spec is clear: the scan is officially
> cancelled once the current call returns with SANE_CANCELLED.
True.
> b) If you are *not* in the middle of another sane call, what happens?
> If I call sane_cancel() in between calls to sane_read(), is the scan
> cancelled immediately upon returning from sane_cancel(), or are you
> allowed or required to call sane_read() once more so that you get a
> return value of SANE_CANCELLED?
From the context of the description of sane_cancel I think the scan is
Status: O
cancelled immediately in this case. I don't think it's forbidden to
call sane_read again but the backend shouldn't depend on that.
> c) The above behavior would give everything an overall consistent behavior:
> 1) An image acquisition cycle begins when sane_start() is called.
> 2) An image acquisition cycle ends if sane_start() returns a value
> which is not SANE_STATUS_GOOD, or when sane_read() returns a
> value which is not SANE_STATUS_GOOD.
> In this model, one must call sane_read() one last time to finish the
> scan, and that is when any file descriptors should be cleaned up.
>
> But this conflicts with the requirement that sane_cancel() be called
> at the end of a scan. It seems to me that sane_cancel() is actually
> being overloaded; it shouldn't serve as both a post-scan clean-up
> function and as the 'stop now' signalling function.
Maybe we should use "sane_end" or a similar function for the normal
end of a scan.
> (Someone will say enforcing such a model would break almost all of
> the current backends. Oh well, maybe for version 2.0....)
That's definitely 2.0 stuff.
> If sane_read() or sane_start() return SANE_STATUS_CANCELLED, does
> sane_cancel() *still* need to be called? The strict reading of the
> specification would say "yes".
As far as I understand the standard, it's only necessary to call
sane_cancel once. The scan is finished immediately or in the case of
an interrupted function, at the end of that function.
If the backend returns SANE_STATUS_CANCELLED without a previous call
to sane_cancel I guess it's just not complient to the standard.
> d) Anyhow, all that aside, it seems to me that if select() is waiting
> on a file descriptor fd, then it is bad asynchronous behavior for
> a call to sane_cancel() in a signal handler to close that fd.
> (Presumably the fd is connected to a pipe connecting to a reader
> process spawned by the backend. The far-end of that pipe should
> be closed, causing the select() to see a pending EOF on the fd.)
Maybe, but that's not in the standard :-)
> However, select() should return an EINTR if it is hit by a signal,
> and calling select() again should then return EBADF if the fd is
> gone....
I think I tried that once and that worked.
> e) Maybe using the "IOChannel" facilities of GDK instead of gdk_input
> would work better? (Just looked at the manpages; seems to be able
> to do stuff in the case of other error conditions.)
No idea.
> f) There are *no* return codes listed for sane_get_parameters().
> One of the possible return values should be SANE_STATUS_CANCELLED,
> in case the scan has been cancelled between the sane_start() and
> the sane_get_parameters() calls.
As sane_get_parameters can be called before sane_start, I don't think
that this is correct.
> I say make the current behavior explicit:
>
> a) If an option group is tagged with SANE_CAP_ADVANCED, then all of the
> options within it are considered advanced options, and the frontend
> should display, or not display, the whole group depending on the user's
> preference.
> The constituent options in the group inherit the ADVANCED tag from the
> group, and it does not matter whether they have the tag or not.
>
> b) If an option group is _not_ tagged with SANE_CAP_ADVANCED, then the
> options within it may individually be tagged as ADVANCED options, and
> the frontend should display them as such.
I will probably add that to doc/backend-writing.txt as it's more a
hint on how to display options.
Bye,
Henning