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))