On Fri, 2006-01-06 at 10:30 +0100, Hoehle, Joerg-Cyril wrote:
And the general answer is: don't exit non-locally across callbacks! It can always lead to unforeseen trouble.
After writing the callbacks section (see Tutorial-Callbacks in http://csserver.evansville.edu/~sc87/cffi/tutorial.texi) I decided to explore whether CFFI could (or should, even) provide a general non-local exit prevention. The answer is, with some difficulty and an interface change, perhaps.
On Lisps with EXIT-EXTENT:MEDIUM, this can be implemented with an unwind-protect form in defcallback [1], which performs the operation posted (as undefined in MINIMAL). Lisps with built-in protection in callback definition don't need this.
As an aside: would it be better for the defcallback semantics to simply say "don't exit non-locally through a C frame"?
Exactly. It's the only sensible thing to do. Ideally, every callback should contain something similar to ignore-errors (e.g. X event loops).
The tutorial does this.
It would probably make callbacks (and perhaps callouts, for that matter) cheaper to call,
I don't understand that implication.
If CFFI is to provide general unwind prevention as stated above, the EXIT-EXTENT:MEDIUM would entail the overhead of always entering an unwind-protect. In addition, if one wanted the "other side" to signal an error indicating that Lisp tried to unwind a C frame, a flag check would have to be added to every foreign funcall. [2] I don't, but the possibility remains.
defcallback doesn't provide this now, and maybe shouldn't at all. In the tutorial, a value must be computed and returned to indicate an error; a parameter would have to be added to defcallback to do this, assuming you care whether C knows that there was some error.
[1] This does not protect you from non-local exits in the handler code, as that would entail another unwind-protect, which itself would have unprotected code ... however, it protects all of the important part -- user code.
[2] Not really important when you're doing a bunch of generic function calls under cffi-new-translators anyway, I suppose.