[3.13] gh-119369: Fix deadlock during thread exit in free-threaded build (GH-119528) (#119868)

Release the GIL before calling `_Py_qsbr_unregister`.

The deadlock could occur when the GIL was enabled at runtime. The
`_Py_qsbr_unregister` call might block while holding the GIL because the
thread state was not active, but the GIL was still held.
(cherry picked from commit 078b8c8cf2)

Co-authored-by: Sam Gross <colesbury@gmail.com>
This commit is contained in:
Miss Islington (bot) 2024-05-31 20:19:38 +02:00 committed by GitHub
parent 5e8396e684
commit a7e81fdfc1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 19 additions and 9 deletions

View file

@ -236,6 +236,11 @@ _Py_qsbr_unregister(PyThreadState *tstate)
struct _qsbr_shared *shared = &tstate->interp->qsbr;
struct _PyThreadStateImpl *tstate_imp = (_PyThreadStateImpl*) tstate;
// gh-119369: GIL must be released (if held) to prevent deadlocks, because
// we might not have an active tstate, which means taht blocking on PyMutex
// locks will not implicitly release the GIL.
assert(!tstate->_status.holds_gil);
PyMutex_Lock(&shared->mutex);
// NOTE: we must load (or reload) the thread state's qbsr inside the mutex
// because the array may have been resized (changing tstate->qsbr) while