[sane-devel] SANE2 standard revisited: Code flow
Mon, 9 Dec 2002 19:53:33 -0500
>From: Oliver Rauch <firstname.lastname@example.org>
>Date: Mon, 9 Dec 2002 23:36:22 +0100
>On Friday 06 December 2002 20:24, Henning Meier-Geinitz wrote:
>but this would make the sane_cancel unnecessaryly complex
>because you have to call
> while (sane_read != SANE_STATUS_EOF);
>and wait until sane_read really reutrnes SANE_STATUS_EOF.
>I suggest to keep this like it is: no need to call sane_read when
>sane_cancel is called!
I don't like the semantics of sane_cancel(), because they are overloaded
The problem is that a backend may have resources that need to be cleaned
up at the end of a scan. sane_cancel() should not be used to both
(a) asynchronously signal a cancel request, and (b) clean up the resources.
Why? Because those resources may be in use if during an asynchonous call.
(I.e. sane_canel() can't free a buffer being used by sane_read() while
in the middle of sane_read()!)
To make such a set-up work requires a lot of real careful coding, and flags,
and it probably introduces race conditions that are unavoidable.
I propose that sane_cancel() be used *only* to request the end of a scan,
and any/all cleanup should be done in sane_start() or sane_read().
Here is my proposal:
Remove the get_select_fd() stuff.
Remove the multi-frame stuff.
Change sane_start() so that it also returns to true image parameters:
SANE_Status sane_start(SANE_Handle h, SANE_Parameters *p);
[since sane_get_parameters() is *always* called after sane_start().
Allowing sane_start() to simply return the true parameters itself
prevents some confusion involving sane_cancel() later on...]
1) Semantics of Image Acquisition Cycle ["IAC"]:
a) An IAC begins when sane_start() is called.
b) During an IAC, the only device-dependent functions (those requiring
a device handle) which may be called are:
c) An IAC ends when sane_read() or sane_start() returns unsuccessfully
(status != SANE_STATUS_GOOD).
At the end of the cycle (during that last call to sane_read() or
sane_start()), the backend is allowed to free any resources which
it allocated for the cycle.
d) An IAC ends *successfully* if it ends due to sane_read() returning
(status == SANE_STATUS_EOF).
Otherwise, the IAC has ended in *failure*.
2) Semantics of sane_cancel():
a) sane_cancel() may be called, asynchronously or synchronously, to tell
the backend to abort the current IAC.
If no IAC is in progress, sane_cancel() has no effect.
b) If sane_cancel() is called synchronously, the next call to sane_read()
is guaranteed to return (status != SANE_STATUS_GOOD) and the IAC is
guaranteed to end.
(The IAC may still end successfully, however.)
c) If sane_cancel() is called asynchronously, during the exection of
sane_start() or sane_read(), then that function should unblock and
return as quickly as possible.
However, following (1c) above, unless that sane_start() or sane_read()
returns (status != SANE_STATUS_GOOD), the image acquisition cycle is
not yet finished.
[This is because the function may be in the midst of returning
SANE_STATUS_GOOD when sane_cancel() is called!]
Thus, one last call to sane_read() may be required.
-matt "semantics, semantics, semantics!" m.