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


6.9.12 Known problems

The unwind protection mechanism may misbehave in some cases. Specifically the unwind handler may not be called in the following cases:

Raising exceptions from an exception handler

In the following example an exception is raised by an exception handler: the unwind handler is called, but the original exception is lost.

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

(with-result
  (guard (E (else
             (add-result 'guard-else)
             E))
    (with-exception-handler
        (lambda (E)
          (add-result 'exception-handler)
          (raise 2))
      (lambda ()
        (with-unwind-protection
            (lambda (why)
              (add-result 'unwind-handler))
          (lambda ()
            (dynamic-wind
                (lambda ()
                  (add-result 'in-guard))
                (lambda ()
                  (add-result 'thunk-in)
                  (raise 1)
                  (add-result 'thunk-out))
                (lambda ()
                  (add-result 'out-guard)))))))))
⇒ (2 (in-guard
       thunk-in
       exception-handler
       out-guard
       in-guard out-guard unwind-handler
       guard-else))

Raising exceptions from a guard’s test

In the following example an exception is raised from a guard’s test expression: the unwind handler is not called and the original exception is lost.

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

(with-result
  (guard (E (else
             (add-result 'outer-guard-else)
             E))
    (guard (E ((begin
                 (add-result 'inner-guard-test)
                 (raise 2))
               E))
      (with-unwind-protection
          (lambda (why)
            (add-result 'unwind-handler))
        (lambda ()
          (dynamic-wind
              (lambda ()
                (add-result 'in-guard))
              (lambda ()
                (add-result 'thunk-in)
                (raise 1)
                (add-result 'thunk-out))
              (lambda ()
                (add-result 'out-guard))))))))
⇒ (2 (in-guard
       thunk-in
       out-guard
       inner-guard-test
       outer-guard-else))

Raising exceptions from dynamic-wind guards

In the following example an exception is raised from a dynamic-wind’s in–guard thunk: the unwind handler is not called and the original exception is lost.

(with-result
  (guard (E (else
             (add-result 'guard-else)
             E))
    (dynamic-wind
        (let ((flag #f))
          (lambda ()
            (cond (flag
                   (add-result 'in-guard/raise)
                   (raise 2))
                  (else
                   (set! flag #t)
                   (add-result 'in-guard)))))
        (lambda ()
          (with-unwind-handler
              (lambda (E)
                (add-result 'unwind-handler))
            (lambda ()
              (add-result 'thunk-in)
              (raise 1))))
        (lambda ()
          (add-result 'out-guard)))))
⇒ (2 (in-guard
       thunk-in
       out-guard
       in-guard/raise
       guard-else))

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