Commit 07291441 authored by simonmar's avatar simonmar
Browse files

[project @ 2004-09-28 15:08:58 by simonmar]

rts_evalStableIO: set rtsApiCapability to NULL *before* calling
scheduleWaitThread, matching the way the other eval_* functions do

The previous way lead to a suble race condition:
  - thread A calls rts_evalIO, enters scheduleWaitThread()
    (rtsApiCapability == NULL).
  - thread B calls rts_evalStableIO, creates a main thread and enters
    scheduleWaitThread() (rtsApiCapability == &MainCapability)
  - thread A exits scheduleWaitThread, sees that rtsApiCapability is
    non-NULL, and calls releaseCapability() on it.  This is bogus,
    because thread A doesn't actually hold the capability, and we've
    done a double-release.

This scenario leads to assertion failures in a debug threaded RTS, and
probably crashes in a non-debug threaded RTS.

parent c6226d8a
......@@ -430,11 +430,12 @@ rts_evalStableIO (HsStablePtr s, /*out*/HsStablePtr *ret)
StgTSO* tso;
StgClosure *p, *r;
SchedulerStatus stat;
Capability *cap = rtsApiCapability;
rtsApiCapability = NULL;
p = (StgClosure *)deRefStablePtr(s);
tso = createStrictIOThread(RtsFlags.GcFlags.initialStkSize, p);
stat = scheduleWaitThread(tso,&r,rtsApiCapability);
rtsApiCapability = NULL;
stat = scheduleWaitThread(tso,&r,cap);
if (stat == Success && ret != NULL) {
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment