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>
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;