diff options
author | Eric Snow <ericsnowcurrently@gmail.com> | 2023-09-27 19:41:06 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-09-27 19:41:06 (GMT) |
commit | 32466c97c06ee5812923d695195394c736eeb707 (patch) | |
tree | e5de52c5dcc30067c6cd79fa97b66d104f911ea4 /Python/pystate.c | |
parent | f49958c886a2f2608f1008186d588efc2a98b445 (diff) | |
download | cpython-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/pystate.c')
-rw-r--r-- | Python/pystate.c | 17 |
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; } |