]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
GH-102126: fix deadlock at shutdown when clearing thread states (#102222)
authorKumar Aditya <59607654+kumaraditya303@users.noreply.github.com>
Sat, 25 Feb 2023 06:51:36 +0000 (12:21 +0530)
committerGitHub <noreply@github.com>
Sat, 25 Feb 2023 06:51:36 +0000 (12:21 +0530)
Misc/NEWS.d/next/Core and Builtins/2023-02-24-17-59-39.gh-issue-102126.HTT8Vc.rst [new file with mode: 0644]
Python/pystate.c

diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-02-24-17-59-39.gh-issue-102126.HTT8Vc.rst b/Misc/NEWS.d/next/Core and Builtins/2023-02-24-17-59-39.gh-issue-102126.HTT8Vc.rst
new file mode 100644 (file)
index 0000000..68c4368
--- /dev/null
@@ -0,0 +1 @@
+Fix deadlock at shutdown when clearing thread states if any finalizer tries to acquire the runtime head lock. Patch by Kumar Aditya.
index 32b17fd19e348f462901d016c4469d439b06da1f..3c655bf3895850cf6a9ee37e3fce0694836636da 100644 (file)
@@ -754,12 +754,19 @@ interpreter_clear(PyInterpreterState *interp, PyThreadState *tstate)
         _PyErr_Clear(tstate);
     }
 
+    // Clear the current/main thread state last.
     HEAD_LOCK(runtime);
-    // XXX Clear the current/main thread state last.
-    for (PyThreadState *p = interp->threads.head; p != NULL; p = p->next) {
+    PyThreadState *p = interp->threads.head;
+    HEAD_UNLOCK(runtime);
+    while (p != NULL) {
+        // See https://github.com/python/cpython/issues/102126
+        // Must be called without HEAD_LOCK held as it can deadlock
+        // if any finalizer tries to acquire that lock.
         PyThreadState_Clear(p);
+        HEAD_LOCK(runtime);
+        p = p->next;
+        HEAD_UNLOCK(runtime);
     }
-    HEAD_UNLOCK(runtime);
 
     /* It is possible that any of the objects below have a finalizer
        that runs Python code or otherwise relies on a thread state