[racket-dev] TR tests sometimes fail with a promise error

From: Vincent St-Amour (stamourv at ccs.neu.edu)
Date: Fri May 3 11:45:38 EDT 2013

Sam, Asumu and I found and fixed the bug. Here's the problem in a
nutshell.

This is the implementation of `delay/thread' from racket/promise.

    (define (delay/thread thunk)
      (let ()
        (define (run)
          (call-with-exception-handler
           (lambda (e) (pset! p (make-reraise e)) (kill-thread (current-thread)))
           (lambda () (pset! p (call-with-values thunk list)))))
        (define p
          (make-promise/thread
           (make-running-thread
            (object-name thunk)
            (thread run))))
        p))

`run' depends on `p', and vice versa. The `run' thread may start
executing *before* `p' is actually defined. This causes `pset!' (which
is just promise mutation) to mutate `#<undefined>', which raises an
exception[1]. The exception handler then calls `pset!' again, which
raises an exception, and kills the thread without setting the promise's
value.

Our solution is to have `run' block on a channel until `p' is fully
initialized. I'll push the fix.

Vincent


[1] Actually, since `pset!' uses `unsafe-struct-set!', there is no
    actual exception. The thread gets killed some other way.


At Thu, 2 May 2013 22:27:14 -0400,
Asumu Takikawa wrote:
> 
> On 2013-05-02 22:14:44 -0400, Asumu Takikawa wrote:
> > This produces a promise error on every third or fifth run or so for me.
> > Commenting out the #:when line makes it work, very oddly.
> 
> Tried it on another machine, the #:when line didn't matter there. Also,
> I can reproduce this more reliably on a machine with fewer cores.
> 
> Cheers,
> Asumu
> _________________________
>   Racket Developers list:
>   http://lists.racket-lang.org/dev

Posted on the dev mailing list.