diff options
author | Sam Gross <colesbury@gmail.com> | 2024-03-08 17:39:53 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-08 17:39:53 (GMT) |
commit | cca30230d992c46dfb607dcc24b3dc2e6d05f536 (patch) | |
tree | 171669b5ce0ef42762da805aeb00d8c110249ba0 /Python | |
parent | 7cee276d551a41d9271daf2a6bcd7def55555973 (diff) | |
download | cpython-cca30230d992c46dfb607dcc24b3dc2e6d05f536.zip cpython-cca30230d992c46dfb607dcc24b3dc2e6d05f536.tar.gz cpython-cca30230d992c46dfb607dcc24b3dc2e6d05f536.tar.bz2 |
gh-115103: Fix unregistering of QSBR state (#116480)
If a thread blocks while waiting on the `shared->mutex` lock, the array
of QSBR states may be reallocated. The `tstate->qsbr` values before the
lock is acquired may not be the same as the value after the lock is acquired.
Diffstat (limited to 'Python')
-rw-r--r-- | Python/qsbr.c | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/Python/qsbr.c b/Python/qsbr.c index 69f77f4..d7ac8f4 100644 --- a/Python/qsbr.c +++ b/Python/qsbr.c @@ -233,13 +233,17 @@ _Py_qsbr_register(_PyThreadStateImpl *tstate, PyInterpreterState *interp, void _Py_qsbr_unregister(_PyThreadStateImpl *tstate) { + struct _qsbr_shared *shared = tstate->qsbr->shared; + + 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 + // we waited to acquire the mutex. struct _qsbr_thread_state *qsbr = tstate->qsbr; - struct _qsbr_shared *shared = qsbr->shared; assert(qsbr->seq == 0 && "thread state must be detached"); - - PyMutex_Lock(&shared->mutex); assert(qsbr->allocated && qsbr->tstate == (PyThreadState *)tstate); + tstate->qsbr = NULL; qsbr->tstate = NULL; qsbr->allocated = false; |