Next: , Previous: , Up: iklib unwind-protect   [Index]


6.9.10 Handling reentering continuations

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