>From: Oliver Rauch <oliver.ra...@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.