diff options
author | Simon Marlow <simonmar@microsoft.com> | 2007-09-14 14:55:19 +0000 |
---|---|---|
committer | Simon Marlow <simonmar@microsoft.com> | 2007-09-14 14:55:19 +0000 |
commit | 442099ad2dbcc007b137745b9246116f06c8723d (patch) | |
tree | 130b2bde43028a5bf23bf98a51b4b69b73628aa4 /rts | |
parent | 0a148fd7108528d6cb1596b5017888c1b558220d (diff) | |
download | haskell-442099ad2dbcc007b137745b9246116f06c8723d.tar.gz |
attempt to fix #1391, hold locks across fork() and initialize them in the child
Diffstat (limited to 'rts')
-rw-r--r-- | rts/Schedule.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/rts/Schedule.c b/rts/Schedule.c index 5ebb685a02..22e61203a3 100644 --- a/rts/Schedule.c +++ b/rts/Schedule.c @@ -2137,16 +2137,31 @@ forkProcess(HsStablePtr *entry // ToDo: for SMP, we should probably acquire *all* the capabilities cap = rts_lock(); + // no funny business: hold locks while we fork, otherwise if some + // other thread is holding a lock when the fork happens, the data + // structure protected by the lock will forever be in an + // inconsistent state in the child. See also #1391. + ACQUIRE_LOCK(&sched_mutex); + ACQUIRE_LOCK(&cap->lock); + pid = fork(); if (pid) { // parent + RELEASE_LOCK(&sched_mutex); + RELEASE_LOCK(&cap->lock); + // just return the pid rts_unlock(cap); return pid; } else { // child +#if defined(THREADED_RTS) + initMutex(&sched_mutex); + initMutex(&cap->lock); +#endif + // Now, all OS threads except the thread that forked are // stopped. We need to stop all Haskell threads, including // those involved in foreign calls. Also we need to delete |