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