summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorEric Snow <ericsnowcurrently@gmail.com>2023-09-27 19:41:06 (GMT)
committerGitHub <noreply@github.com>2023-09-27 19:41:06 (GMT)
commit32466c97c06ee5812923d695195394c736eeb707 (patch)
treee5de52c5dcc30067c6cd79fa97b66d104f911ea4 /Python
parentf49958c886a2f2608f1008186d588efc2a98b445 (diff)
downloadcpython-32466c97c06ee5812923d695195394c736eeb707.zip
cpython-32466c97c06ee5812923d695195394c736eeb707.tar.gz
cpython-32466c97c06ee5812923d695195394c736eeb707.tar.bz2
gh-109793: Allow Switching Interpreters During Finalization (gh-109794)
Essentially, we should check the thread ID rather than the thread state pointer.
Diffstat (limited to 'Python')
-rw-r--r--Python/pystate.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/Python/pystate.c b/Python/pystate.c
index dcc6c11..570b524 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -2964,11 +2964,26 @@ _PyThreadState_MustExit(PyThreadState *tstate)
tstate->interp->runtime to support calls from Python daemon threads.
After Py_Finalize() has been called, tstate can be a dangling pointer:
point to PyThreadState freed memory. */
+ unsigned long finalizing_id = _PyRuntimeState_GetFinalizingID(&_PyRuntime);
PyThreadState *finalizing = _PyRuntimeState_GetFinalizing(&_PyRuntime);
if (finalizing == NULL) {
+ // XXX This isn't completely safe from daemon thraeds,
+ // since tstate might be a dangling pointer.
finalizing = _PyInterpreterState_GetFinalizing(tstate->interp);
+ finalizing_id = _PyInterpreterState_GetFinalizingID(tstate->interp);
}
- return (finalizing != NULL && finalizing != tstate);
+ // XXX else check &_PyRuntime._main_interpreter._initial_thread
+ if (finalizing == NULL) {
+ return 0;
+ }
+ else if (finalizing == tstate) {
+ return 0;
+ }
+ else if (finalizing_id == PyThread_get_thread_ident()) {
+ /* gh-109793: we must have switched interpreters. */
+ return 0;
+ }
+ return 1;
}