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