diff options
author | Sam Gross <colesbury@gmail.com> | 2024-03-08 20:26:36 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-08 20:26:36 (GMT) |
commit | 3cdfdc07a9dd39bcd6855b8c104584f9c34624f2 (patch) | |
tree | 49ef235f2dc7b40cc713dffdc5f9391effa4e0b5 | |
parent | 601f3a7b3391e9d219a8ec44a6c56d00ce584d2a (diff) | |
download | cpython-3cdfdc07a9dd39bcd6855b8c104584f9c34624f2.zip cpython-3cdfdc07a9dd39bcd6855b8c104584f9c34624f2.tar.gz cpython-3cdfdc07a9dd39bcd6855b8c104584f9c34624f2.tar.bz2 |
gh-108724: Fix _PySemaphore_Wait call during thread deletion (#116483)
In general, when `_PyThreadState_GET()` is non-NULL then the current
thread is "attached", but there is a small window during
`PyThreadState_DeleteCurrent()` where that's not true:
tstate_delete_common() is called when the thread is detached, but before
current_fast_clear().
Co-authored-by: Eric Snow <ericsnowcurrently@gmail.com>
-rw-r--r-- | Python/parking_lot.c | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/Python/parking_lot.c b/Python/parking_lot.c index 0a897f9..d5877fe 100644 --- a/Python/parking_lot.c +++ b/Python/parking_lot.c @@ -194,14 +194,16 @@ _PySemaphore_Wait(_PySemaphore *sema, PyTime_t timeout, int detach) PyThreadState *tstate = NULL; if (detach) { tstate = _PyThreadState_GET(); - if (tstate) { + if (tstate && tstate->state == _Py_THREAD_ATTACHED) { + // Only detach if we are attached PyEval_ReleaseThread(tstate); } + else { + tstate = NULL; + } } - int res = _PySemaphore_PlatformWait(sema, timeout); - - if (detach && tstate) { + if (tstate) { PyEval_AcquireThread(tstate); } return res; |