mirror of https://github.com/python/cpython
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.
This commit is contained in:
parent
7cee276d55
commit
cca30230d9
|
@ -233,13 +233,17 @@ _Py_qsbr_register(_PyThreadStateImpl *tstate, PyInterpreterState *interp,
|
||||||
void
|
void
|
||||||
_Py_qsbr_unregister(_PyThreadStateImpl *tstate)
|
_Py_qsbr_unregister(_PyThreadStateImpl *tstate)
|
||||||
{
|
{
|
||||||
struct _qsbr_thread_state *qsbr = tstate->qsbr;
|
struct _qsbr_shared *shared = tstate->qsbr->shared;
|
||||||
struct _qsbr_shared *shared = qsbr->shared;
|
|
||||||
|
|
||||||
assert(qsbr->seq == 0 && "thread state must be detached");
|
|
||||||
|
|
||||||
PyMutex_Lock(&shared->mutex);
|
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;
|
||||||
|
|
||||||
|
assert(qsbr->seq == 0 && "thread state must be detached");
|
||||||
assert(qsbr->allocated && qsbr->tstate == (PyThreadState *)tstate);
|
assert(qsbr->allocated && qsbr->tstate == (PyThreadState *)tstate);
|
||||||
|
|
||||||
tstate->qsbr = NULL;
|
tstate->qsbr = NULL;
|
||||||
qsbr->tstate = NULL;
|
qsbr->tstate = NULL;
|
||||||
qsbr->allocated = false;
|
qsbr->allocated = false;
|
||||||
|
|
Loading…
Reference in New Issue