[plt-dev] Error message from test-engine

From: Robby Findler (robby at eecs.northwestern.edu)
Date: Mon Nov 16 21:06:25 EST 2009

The promise in question has been there for a very long time (10+
years, I'd guess), but there definitely could be treading problems.
Perhaps just changing (in framework/private/icon.ss) to use the new
thread safe stuff is the right thing.


On Mon, Nov 16, 2009 at 7:36 PM, Eli Barzilay <eli at barzilay.org> wrote:
> On Nov 16, Carl Eastlund wrote:
>> I got the following error while trying to modify the way Dracula uses
>> check-expect tests:
>> force: reentrant promise gc-on-bitmap
>> [...]
>> I don't think anything I did should cause this, but I'm not sure
>> quite what happened so I can't say for sure.  I do know my program
>> had two check-expect tests, and when this error showed up the
>> check-expect output displayed three results (my first test once and
>> my second test twice).
>> Does anyone know what might be causing this?
> This error happens when a promise is forced while it is forced.  For
> example:
>  -> (define p (delay (force p)))
>  -> (force p)
>  force: reentrant promise p
> This is especially tricky when multiple threads are involved:
>  -> (define p (delay (sleep 5)))
>  -> (thread (lambda () (force p)))
>  #<thread>
>  -> (force p)
>  force: reentrant promise p
> which could be a problem since threads are involved.
> As for what Robby said -- I comitted some major extension to
> `scheme/promise', but the plain `delay'/`force'/`lazy' should be doing
> exactly the same thing they did before, so no *new* problems should be
> introduced.
> So, what I think you should do now is:
> 1. Try to undo my changes to `scheme/promise' and see if you get the
>   same error.  You can just use the contents of the file from 4.2.2
>   for this.  If it doesn't fail, then there might be a bug in the
>   extension, and I'll need some minimal-ish code that reproduces it.
> 2. But I think that it's likely it will fail too.  In that case,
>   you're probably running against the thread problem that I've
>   demonstrated above.  (If you look at your stack trace, you'll see
>   that there is one `force/generic', which is what you'd get from my
>   thread example, but the first one will have two.)
>   The good news is that one of the new extensions that I added is
>   `delay/sync' -- this is a kind of a promise that can be forced from
>   multiple threads, the first one will compute it and the rest will
>   block until it's ready.  So, if it does fail, you should look
>   around for code that uses `delay'/`force', and see if you can fix
>   it by using `delay/sync'.
> BTW, this restriction that makes plain promises less useful with
> multiple threads is relatively new (since v4).  The older version
> wouldn't throw that error -- but it would have the obvious race
> conditions, which means that the promise will be forced multiple time,
> and one will get to stay.
> --
>          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
>                    http://barzilay.org/                   Maze is Life!
> _________________________________________________
>  For list-related administrative tasks:
>  http://list.cs.brown.edu/mailman/listinfo/plt-dev

Posted on the dev mailing list.