Re: DYNAMIC-WIND before and after procedures are not protected from interruption
Robert Ransom <[email protected]> Thu, 24 Dec 2009 00:50:28 -0800
| Newsgroups | gmane.lisp.scheme.scheme48 |
|---|---|
| Message-ID | <[email protected]> |
On Thu, 24 Dec 2009 02:31:26 -0500 Taylor R Campbell <[email protected]> wrote: > Because DYNAMIC-WIND before and after procedures are not protected > from interruption, it is not possible, for example, to reliably > release a lock in Scheme48 when control exits an extent: in > > (dynamic-wind > (let ((already? #f)) > (lambda () > (if already? (error "Reentry into locked extent prohibited.")) > (set! already? #t) > (obtain-lock lock))) > (lambda () ...) > (lambda () > (release-lock lock))), > > if control is interrupted just before the call to RELEASE-LOCK, and > non-locally exited (e.g., by hitting ^C at the REPL and then typing > ,reset), then the lock will not be released as intended. You don't need to interrupt that code snippet during the after thunk to keep it from releasing its lock: > ,open debug-messages threads > (define (make-print-thunk . xs) (lambda () (apply debug-message xs))) ; no values returned > (dynamic-wind (make-print-thunk "<in>") (lambda () (sleep 10000)) (make-print-thunk "<out>")) <in> ^C interrupt: keyboard interrupt [command-level-event-handler] keyboard 1> ,pop <out> ; no values returned > And R6RS specifies that exception handlers are called in the dynamic environment of the exception (except that the current exception handler is taken from the dynamic environment in which the exception handler was installed), so any system which implements R6RS exceptions as specified and handles external interrupts like ^C using the same machinery will produce the same behavior. Robert Ransom