Commit ea3d1efb authored by Simon Marlow's avatar Simon Marlow

Fix a crash in requestSync()

It was possible for a thread to read invalid memory after a conflict
when multiple threads were synchronising.

I haven't been successful in constructing a test case that triggers
this, but we have some internal code that ran into it.
parent e996e85f
......@@ -1416,25 +1416,30 @@ static void stopAllCapabilities (Capability **pCap, Task *task)
#if defined(THREADED_RTS)
static rtsBool requestSync (
Capability **pcap, Task *task, PendingSync *sync,
Capability **pcap, Task *task, PendingSync *new_sync,
SyncType *prev_sync_type)
{
PendingSync *prev_sync;
PendingSync *sync;
prev_sync = (PendingSync*)cas((StgVolatilePtr)&pending_sync,
(StgWord)NULL,
(StgWord)sync);
sync = (PendingSync*)cas((StgVolatilePtr)&pending_sync,
(StgWord)NULL,
(StgWord)new_sync);
if (prev_sync)
if (sync != NULL)
{
// sync is valid until we have called yieldCapability().
// After the sync is completed, we cannot read that struct any
// more because it has been freed.
*prev_sync_type = sync->type;
do {
debugTrace(DEBUG_sched, "someone else is trying to sync (%d)...",
prev_sync->type);
sync->type);
ASSERT(*pcap);
yieldCapability(pcap,task,rtsTrue);
} while (pending_sync);
sync = pending_sync;
} while (sync != NULL);
// NOTE: task->cap might have changed now
*prev_sync_type = prev_sync->type;
return rtsTrue;
}
else
......
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