<div dir="ltr">Yes (I wrote this privately to Vincent too).<div><br></div><div>Also, it has the advantage of being clear that you're not sending any meaningful values (for future maintainers of this code).</div><div><br>
</div><div>Robby</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Fri, May 3, 2013 at 11:06 AM, Vincent St-Amour <span dir="ltr"><<a href="mailto:stamourv@ccs.neu.edu" target="_blank">stamourv@ccs.neu.edu</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Sounds good, I'll use a semaphore.<br>
<br>
Vincent<br>
<br>
<br>
At Fri, 3 May 2013 09:58:25 -0600,<br>
<div class="HOEnZb"><div class="h5">Matthew Flatt wrote:<br>
><br>
> Thanks for tracking this down!<br>
><br>
> In case you mean a channel in the sense of `make-channel', I recommend<br>
> a semaphore, instead, since a semaphore is the lightest-weight<br>
> synchronization construct.<br>
><br>
> At Fri, 03 May 2013 11:45:38 -0400, Vincent St-Amour wrote:<br>
> > Sam, Asumu and I found and fixed the bug. Here's the problem in a<br>
> > nutshell.<br>
> ><br>
> > This is the implementation of `delay/thread' from racket/promise.<br>
> ><br>
> > (define (delay/thread thunk)<br>
> > (let ()<br>
> > (define (run)<br>
> > (call-with-exception-handler<br>
> > (lambda (e) (pset! p (make-reraise e)) (kill-thread<br>
> > (current-thread)))<br>
> > (lambda () (pset! p (call-with-values thunk list)))))<br>
> > (define p<br>
> > (make-promise/thread<br>
> > (make-running-thread<br>
> > (object-name thunk)<br>
> > (thread run))))<br>
> > p))<br>
> ><br>
> > `run' depends on `p', and vice versa. The `run' thread may start<br>
> > executing *before* `p' is actually defined. This causes `pset!' (which<br>
> > is just promise mutation) to mutate `#<undefined>', which raises an<br>
> > exception[1]. The exception handler then calls `pset!' again, which<br>
> > raises an exception, and kills the thread without setting the promise's<br>
> > value.<br>
> ><br>
> > Our solution is to have `run' block on a channel until `p' is fully<br>
> > initialized. I'll push the fix.<br>
> ><br>
> > Vincent<br>
> ><br>
> ><br>
> > [1] Actually, since `pset!' uses `unsafe-struct-set!', there is no<br>
> > actual exception. The thread gets killed some other way.<br>
> ><br>
> ><br>
> > At Thu, 2 May 2013 22:27:14 -0400,<br>
> > Asumu Takikawa wrote:<br>
> > ><br>
> > > On 2013-05-02 22:14:44 -0400, Asumu Takikawa wrote:<br>
> > > > This produces a promise error on every third or fifth run or so for me.<br>
> > > > Commenting out the #:when line makes it work, very oddly.<br>
> > ><br>
> > > Tried it on another machine, the #:when line didn't matter there. Also,<br>
> > > I can reproduce this more reliably on a machine with fewer cores.<br>
> > ><br>
> > > Cheers,<br>
> > > Asumu<br>
> > > _________________________<br>
> > > Racket Developers list:<br>
> > > <a href="http://lists.racket-lang.org/dev" target="_blank">http://lists.racket-lang.org/dev</a><br>
> > _________________________<br>
> > Racket Developers list:<br>
> > <a href="http://lists.racket-lang.org/dev" target="_blank">http://lists.racket-lang.org/dev</a><br>
_________________________<br>
Racket Developers list:<br>
<a href="http://lists.racket-lang.org/dev" target="_blank">http://lists.racket-lang.org/dev</a><br>
</div></div></blockquote></div><br></div>