[plt-scheme] dynamic-wind & kill-thread

From: YC (yinso.chen at gmail.com)
Date: Tue Apr 21 13:42:49 EDT 2009

On Tue, Apr 21, 2009 at 3:42 AM, Robby Findler
<robby at eecs.northwestern.edu>wrote:

> > what happens when a thread is killed in the middle of executing a
> > dynamic-wind block?  Does the post-thunk get executed still?
> No, it doesn't.

Thanks for the verification.

In general, one might have to rewrite the program to make it
> kill-safe. That is, there is no way to just take code that
> synchronizes in some arbitrary way and make it kill-safe. Perhaps if
> you can say more about what the actual syncronization protocol is, we
> can help you make it kill-safe.

I try to verify the possibility first to ensure my bug report is not bogus

The blocked code exists in planet package schematics spgsql.plt, in
private/p3.ss & private/connection.ss.  Inside - it uses a semaphore to lock
the critical region.  The function protocol3:new-exchange waits for the
semaphore, and protocol3:end-exchange releases the semaphore.

protocol3:end-exchange appears to be only called by base%:end-exchange in
private/connection.ss, which appears to be only called in
primitive-query-mixin:with-final-end-exchange, which generates a
dynamic-wind block that calls the end-exchange in post-thunk.

My threads eventually block on protocol3:new-exchange, which appears to be
waiting for a semaphore that's never released (and if dynamic-wind is not
kill-safe that it can explain the behavior).

This behavior is intermittent and hard to reproduce, but definitely there
(as once it happens my app does nothing).  Without Matthew's stack tracing
approach I could not find out where it was blocking and how.

Below is the code snippet from the two files.

;; private/p3.ss
;; protocol3:new-exchange : protocol3 -> stream
(define (protocol3:new-exchange protocol)
  (semaphore-wait (protocol3-ownerlock protocol))
;; protocol3:end-exchange : protocol3 -> void
(define (protocol3:end-exchange protocol)
  (semaphore-post (protocol3-ownerlock protocol)))

;; private/connection.ss
;; base%
(define base%
  (class* object% (base<%>)
    ;; new-exchange : -> stream
    (define/public-final (new-exchange)
      (unless protocol
        (raise-user-error 'connection<%> "not connected"))
      (protocol3:new-exchange protocol))

    ;; end-exchange : -> void
    (define/public-final (end-exchange)
      (unless protocol
        (raise-user-error 'connection<%> "not connected"))
      (protocol3:end-exchange protocol))
(define primitive-query-mixin
  (mixin (base<%>) (primitive-query<%>)
    (define-syntax with-final-end-exchange
      (syntax-rules ()
        [(with-final-end-exchange . b)
             (lambda () . b)
             (lambda () (end-exchange)))]))
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20090421/e920b553/attachment.html>

Posted on the users mailing list.