Skip to content

Commit 9ade043

Browse files
fix deadlock with reentrant calls to get head lock
1 parent 81bf10e commit 9ade043

File tree

1 file changed

+9
-3
lines changed

1 file changed

+9
-3
lines changed

Python/pystate.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -754,12 +754,18 @@ interpreter_clear(PyInterpreterState *interp, PyThreadState *tstate)
754754
_PyErr_Clear(tstate);
755755
}
756756

757+
// Clear the current/main thread state last.
757758
HEAD_LOCK(runtime);
758-
// XXX Clear the current/main thread state last.
759-
for (PyThreadState *p = interp->threads.head; p != NULL; p = p->next) {
759+
PyThreadState *p = interp->threads.head;
760+
HEAD_UNLOCK(runtime);
761+
while (p != NULL) {
762+
// Must be called without HEAD_LOCK held as it can deadlock
763+
// if any finalizer tries to acquire that lock.
760764
PyThreadState_Clear(p);
765+
HEAD_LOCK(runtime);
766+
p = p->next;
767+
HEAD_UNLOCK(runtime);
761768
}
762-
HEAD_UNLOCK(runtime);
763769

764770
/* It is possible that any of the objects below have a finalizer
765771
that runs Python code or otherwise relies on a thread state

0 commit comments

Comments
 (0)