[commit: ghc] ghc-7.8: Avoid deadlock in freeTask (called by forkProcess) (8a6528e)

git at git.haskell.org git at git.haskell.org
Mon Aug 4 13:21:04 UTC 2014


Repository : ssh://git@git.haskell.org/ghc

On branch  : ghc-7.8
Link       : http://ghc.haskell.org/trac/ghc/changeset/8a6528e92aacc3f676f37536ebe3501046d9a774/ghc

>---------------------------------------------------------------

commit 8a6528e92aacc3f676f37536ebe3501046d9a774
Author: Edsko de Vries <edsko at well-typed.com>
Date:   Sun Jul 13 15:19:39 2014 -0500

    Avoid deadlock in freeTask (called by forkProcess)
    
    Summary: Documented in more detail inline with the change.
    
    Test Plan: validate
    
    Reviewers: austin, simonmar, duncan
    
    Reviewed By: austin, simonmar, duncan
    
    Subscribers: simonmar, relrod, carter
    
    Differential Revision: https://phabricator.haskell.org/D59
    
    (cherry picked from commit 39630ab15cc0607103dc4ef3d9089de44ef17c2d)


>---------------------------------------------------------------

8a6528e92aacc3f676f37536ebe3501046d9a774
 rts/Task.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/rts/Task.c b/rts/Task.c
index 12c22c4..e191bd0 100644
--- a/rts/Task.c
+++ b/rts/Task.c
@@ -350,6 +350,20 @@ discardTasksExcept (Task *keep)
         next = task->all_next;
         if (task != keep) {
             debugTrace(DEBUG_sched, "discarding task %" FMT_SizeT "", (size_t)TASK_ID(task));
+#if defined(THREADED_RTS)
+            // It is possible that some of these tasks are currently blocked
+            // (in the parent process) either on their condition variable
+            // `cond` or on their mutex `lock`. If they are we may deadlock
+            // when `freeTask` attempts to call `closeCondition` or
+            // `closeMutex` (the behaviour of these functions is documented to
+            // be undefined in the case that there are threads blocked on
+            // them). To avoid this, we re-initialize both the condition
+            // variable and the mutex before calling `freeTask` (we do
+            // precisely the same for all global locks in `forkProcess`).
+            initCondition(&task->cond);
+            initMutex(&task->lock);
+#endif
+
             // Note that we do not traceTaskDelete here because
             // we are not really deleting a task.
             // The OS threads for all these tasks do not exist in



More information about the ghc-commits mailing list