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,
sync = (PendingSync*)cas((StgVolatilePtr)&pending_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)...",
} while (pending_sync);
sync = pending_sync;
} while (sync != NULL);
// NOTE: task->cap might have changed now
*prev_sync_type = prev_sync->type;
return rtsTrue;
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment