[plt-dev] Error message from test-engine
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!