mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
[3.11] GH-100892: Fix race in clearing threading.local
(GH-100922). (#100937)
(cherry picked from commit 762745a124
)
Co-authored-by: Kumar Aditya <59607654+kumaraditya303@users.noreply.github.com>
This commit is contained in:
parent
1b2459dc64
commit
e707671684
4 changed files with 73 additions and 19 deletions
|
@ -839,6 +839,11 @@ local_traverse(localobject *self, visitproc visit, void *arg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#define HEAD_LOCK(runtime) \
|
||||
PyThread_acquire_lock((runtime)->interpreters.mutex, WAIT_LOCK)
|
||||
#define HEAD_UNLOCK(runtime) \
|
||||
PyThread_release_lock((runtime)->interpreters.mutex)
|
||||
|
||||
static int
|
||||
local_clear(localobject *self)
|
||||
{
|
||||
|
@ -849,18 +854,23 @@ local_clear(localobject *self)
|
|||
/* Remove all strong references to dummies from the thread states */
|
||||
if (self->key) {
|
||||
PyInterpreterState *interp = _PyInterpreterState_GET();
|
||||
_PyRuntimeState *runtime = &_PyRuntime;
|
||||
HEAD_LOCK(runtime);
|
||||
PyThreadState *tstate = PyInterpreterState_ThreadHead(interp);
|
||||
for(; tstate; tstate = PyThreadState_Next(tstate)) {
|
||||
if (tstate->dict == NULL) {
|
||||
continue;
|
||||
}
|
||||
PyObject *v = _PyDict_Pop(tstate->dict, self->key, Py_None);
|
||||
if (v != NULL) {
|
||||
Py_DECREF(v);
|
||||
}
|
||||
else {
|
||||
PyErr_Clear();
|
||||
HEAD_UNLOCK(runtime);
|
||||
while (tstate) {
|
||||
if (tstate->dict) {
|
||||
PyObject *v = _PyDict_Pop(tstate->dict, self->key, Py_None);
|
||||
if (v != NULL) {
|
||||
Py_DECREF(v);
|
||||
}
|
||||
else {
|
||||
PyErr_Clear();
|
||||
}
|
||||
}
|
||||
HEAD_LOCK(runtime);
|
||||
tstate = PyThreadState_Next(tstate);
|
||||
HEAD_UNLOCK(runtime);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue