Skip to content

Commit 3153d7f

Browse files
committed
gh-145685: Avoid contention on TYPE_LOCK in super() lookups
1 parent f26eca7 commit 3153d7f

File tree

1 file changed

+10
-11
lines changed

1 file changed

+10
-11
lines changed

Objects/typeobject.c

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12360,18 +12360,17 @@ _super_lookup_descr(PyTypeObject *su_type, PyTypeObject *su_obj_type, PyObject *
1236012360
PyObject *mro, *res;
1236112361
Py_ssize_t i, n;
1236212362

12363-
BEGIN_TYPE_LOCK();
1236412363
mro = lookup_tp_mro(su_obj_type);
12365-
/* keep a strong reference to mro because su_obj_type->tp_mro can be
12366-
replaced during PyDict_GetItemRef(dict, name, &res) and because
12367-
another thread can modify it after we end the critical section
12368-
below */
12369-
Py_XINCREF(mro);
12370-
END_TYPE_LOCK();
12371-
1237212364
if (mro == NULL)
1237312365
return NULL;
1237412366

12367+
/* Keep a strong reference to mro because su_obj_type->tp_mro can be
12368+
replaced during PyDict_GetItemRef(dict, name, &res). */
12369+
PyThreadState *tstate = _PyThreadState_GET();
12370+
_PyCStackRef mro_ref;
12371+
_PyThreadState_PushCStackRef(tstate, &mro_ref);
12372+
mro_ref.ref = PyStackRef_FromPyObjectNew(mro);
12373+
1237512374
assert(PyTuple_Check(mro));
1237612375
n = PyTuple_GET_SIZE(mro);
1237712376

@@ -12382,7 +12381,7 @@ _super_lookup_descr(PyTypeObject *su_type, PyTypeObject *su_obj_type, PyObject *
1238212381
}
1238312382
i++; /* skip su->type (if any) */
1238412383
if (i >= n) {
12385-
Py_DECREF(mro);
12384+
_PyThreadState_PopCStackRef(tstate, &mro_ref);
1238612385
return NULL;
1238712386
}
1238812387

@@ -12393,13 +12392,13 @@ _super_lookup_descr(PyTypeObject *su_type, PyTypeObject *su_obj_type, PyObject *
1239312392

1239412393
if (PyDict_GetItemRef(dict, name, &res) != 0) {
1239512394
// found or error
12396-
Py_DECREF(mro);
12395+
_PyThreadState_PopCStackRef(tstate, &mro_ref);
1239712396
return res;
1239812397
}
1239912398

1240012399
i++;
1240112400
} while (i < n);
12402-
Py_DECREF(mro);
12401+
_PyThreadState_PopCStackRef(tstate, &mro_ref);
1240312402
return NULL;
1240412403
}
1240512404

0 commit comments

Comments
 (0)