summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorSam Gross <colesbury@gmail.com>2024-03-08 17:39:53 (GMT)
committerGitHub <noreply@github.com>2024-03-08 17:39:53 (GMT)
commitcca30230d992c46dfb607dcc24b3dc2e6d05f536 (patch)
tree171669b5ce0ef42762da805aeb00d8c110249ba0 /Python
parent7cee276d551a41d9271daf2a6bcd7def55555973 (diff)
downloadcpython-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.c10
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;