[3.13] gh-154175: Fetch _PY_GIL_DROP_REQUEST_BIT under GIL (#157013)

gh-154175: Fetch _PY_GIL_DROP_REQUEST_BIT under GIL

Once the GIL is released the tstate may be freed which shows up as ASAN
and TSAN failures in test_io with daemon threads. Check the bit before
dropping the GIL so the tstate is guaranteed to still be allocated.

Remove the TSAN suppressions which were added for 3.13 as this should
fix this case.
This commit is contained in:
Cody Maloney authored and GitHub committed 2026-09-29 23:24:31 +02:00
1 parent d5527b6658
commit 6959d94c01
4 files changed
+10 -8

No files matched your search

+6 -2
View File
@@ -246,11 +246,16 @@ drop_gil(PyInterpreterState *interp, PyThreadState *tstate, int final_release)
Py_FatalError("drop_gil: GIL is not locked");
}
int drop_requested = 0;
if (!final_release) {
/* Sub-interpreter support: threads might have been switched
under our feet using PyThreadState_Swap(). Fix the GIL last
holder variable so that our heuristics work. */
_Py_atomic_store_ptr_relaxed(&gil->last_holder, tstate);
/* Checked here as tstate may freed outside gil. */
drop_requested = _Py_eval_breaker_bit_is_set(tstate,
_PY_GIL_DROP_REQUEST_BIT);
}
drop_gil_impl(tstate, gil);
@@ -262,8 +267,7 @@ drop_gil(PyInterpreterState *interp, PyThreadState *tstate, int final_release)
crash. We can use final_release to indicate the thread is done with the
GIL, and that's the only time we might delete the interpreter. See
https://github.com/python/cpython/issues/104341. */
if (!final_release &&
_Py_eval_breaker_bit_is_set(tstate, _PY_GIL_DROP_REQUEST_BIT)) {
if (!final_release && drop_requested) {
MUTEX_LOCK(gil->switch_mutex);
/* Not switched yet => wait */
if (((PyThreadState*)_Py_atomic_load_ptr_relaxed(&gil->last_holder)) == tstate)