Next: , Previous: , Up: unwind   [Contents][Index]


6.8 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 McCarthy’s amb operator in the ?thunk. 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-handler causes the exception to be raised:

(import (only (mmck checks)
        with-result
        add-result))

(with-result
  (guard (E ((non-reinstatable-violation? E)
             (add-result 'violation)
             #t)
            (else E))
    (let ((rv (with-unwind-handler
                  (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))

Next: , Previous: , Up: unwind   [Contents][Index]

This document describes version 0.1.0-devel.1 of MMCK Exceptional Conditions.