[sane-devel] SANE2 standard revisited: Code flow
Matto Marjanovic
maddog at mir.com
Tue Dec 10 00:53:33 GMT 2002
>From: Oliver Rauch <oliver.rauch at rauch-domain.de>
>Date: Mon, 9 Dec 2002 23:36:22 +0100
>
>On Friday 06 December 2002 20:24, Henning Meier-Geinitz wrote:
>> Proposal:
...
>but this would make the sane_cancel unnecessaryly complex
>because you have to call
>
> sane_cancel
> 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!
>
>Oliver
I don't like the semantics of sane_cancel(), because they are overloaded
and unclear.
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:
0) Prerequisites:
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:
- sane_read()
- sane_cancel()
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.
More information about the sane-devel
mailing list