aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'Python/pystate.c')
-rw-r--r--Python/pystate.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/Python/pystate.c b/Python/pystate.c
index c0d161f894c..dfca3f5fd71 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -396,11 +396,19 @@ interpreter_clear(PyInterpreterState *interp, PyThreadState *tstate)
_PyErr_Clear(tstate);
}
+ // Clear the current/main thread state last.
HEAD_LOCK(runtime);
- 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);
Py_CLEAR(interp->audit_hooks);