;; experiment 1 (define x (make-mutex)) (thread-start! (make-thread (lambda () (dynamic-wind (lambda () (mutex-lock! x)) (lambda () (raise 2)) (lambda () (mutex-unlock! x)))))) (mutex-state x) (mutex-lock! x) ;; experiment 2 (define (current-dynamic-extent) ;; a stripped down version of srfi-154 ;; ;; Note: any unlucky combination of call/cc, e.g., from exception ;; handlers exception handler might result in an obfuscated version ;; of this: ((call-with-current-continuation (lambda (unit) ((lambda (d) (lambda () d)) (lambda (thunk) (call-with-current-continuation (lambda (k) (unit (lambda () (call-with-values thunk k))))))))))) (define (dynamic f #!optional (dynamic-extent #f)) (let ((fixed (if dynamic-extent dynamic-extent (current-dynamic-extent)))) (lambda args (fixed (lambda () (apply f args)))))) ;; Here we go (define (with-mutex m t) (dynamic-wind (lambda () (mutex-lock! m)) t (lambda () (mutex-unlock! m)))) (define x (make-mutex)) (mutex-specific-set! x #t) (define invert-x! (dynamic (lambda () (with-mutex x (lambda () (mutex-specific-set! x (not (mutex-specific x)))))))) (display (with-mutex x (lambda () (let ((before (mutex-specific x))) (invert-x!) ;; I bet you'd expect this to block, don't you? (eq? before (mutex-specific x))))))