Next: iklib unwind-protect dyn-env, Previous: iklib unwind-protect coroutines, Up: iklib unwind-protect [Index]
After the ?unwind-handler is called: we do not want the
execution flow to reenter the ?thunk in the same dynamic extent.
After the dynamic extent of a call to ?thunk terminates, and the
?unwind-handler is called: we are forbidden to reenter the
?thunk; if we try to reenter: an exception of type
&non-reinstatable
is raised.
The first problem with reentering is that the code in the ?thunk expects invariants in the state of the process that are no longer true; for example: if ?unwind-handler closes an input/output port, the ?thunk still expects it to be open.
Reentering might happen, for example, when using the amb
operator in the ?thunk, (vicare-libs)McCarthy’s amb
operator. This means we must be careful to use amb
in a
?thunk only when the whole search never crosses the unwind
protection contour.
The following example shows how calling an escape procedure created in
the ?thunk of a with-unwind-protection
causes the
exception to be raised:
(import (vicare) (only (vicare checks) with-result add-result)) (with-result (guard (E ((non-reinstatable-violation? E) (add-result 'violation) #t) (else E)) (let ((rv (with-unwind-protection (lambda (why) (add-result 'cleanup)) (lambda () (add-result 'body-in) (begin0 (call/cc values) (add-result 'body-out)))))) (cond ((procedure? rv) (add-result 'reinstating) (rv 123)) (else (add-result 'returning) rv))))) ⇒ (#t (body-in body-out cleanup reinstating violation))