aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Python/pylifecycle.c
diff options
context:
space:
mode:
authorSam Gross <colesbury@gmail.com>2024-03-21 14:21:02 -0400
committerGitHub <noreply@github.com>2024-03-21 11:21:02 -0700
commit1f72fb5447ef3f8892b4a7a6213522579c618e8e (patch)
tree43997f5d50ff319adc557320b277a68ddf38099d /Python/pylifecycle.c
parent50369e6c34d05222e5a0ec9443a9f7b230e83112 (diff)
downloadcpython-1f72fb5447ef3f8892b4a7a6213522579c618e8e.tar.gz
cpython-1f72fb5447ef3f8892b4a7a6213522579c618e8e.zip
gh-116522: Refactor `_PyThreadState_DeleteExcept` (#117131)
Split `_PyThreadState_DeleteExcept` into two functions: - `_PyThreadState_RemoveExcept` removes all thread states other than one passed as an argument. It returns the removed thread states as a linked list. - `_PyThreadState_DeleteList` deletes those dead thread states. It may call destructors, so we want to "start the world" before calling `_PyThreadState_DeleteList` to avoid potential deadlocks.
Diffstat (limited to 'Python/pylifecycle.c')
-rw-r--r--Python/pylifecycle.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index 683534d342f..1d315b80d88 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -1934,8 +1934,11 @@ Py_FinalizeEx(void)
will be called in the current Python thread. Since
_PyRuntimeState_SetFinalizing() has been called, no other Python thread
can take the GIL at this point: if they try, they will exit
- immediately. */
- _PyThreadState_DeleteExcept(tstate);
+ immediately. We start the world once we are the only thread state left,
+ before we call destructors. */
+ PyThreadState *list = _PyThreadState_RemoveExcept(tstate);
+ _PyEval_StartTheWorldAll(runtime);
+ _PyThreadState_DeleteList(list);
/* At this point no Python code should be running at all.
The only thread state left should be the main thread of the main