mirror of https://github.com/python/cpython
gh-111926: Avoid locking in PyType_IsSubtype (#117275)
Read the MRO in a thread-unsafe way in `PyType_IsSubtype` to avoid locking. Fixing this is tracked in #117306. The motivation for this change is in support of making weakrefs thread-safe in free-threaded builds: `WeakValueDictionary` uses a special dictionary function, `_PyDict_DelItemIf` to remove dead weakrefs from the dictionary. `_PyDict_DelItemIf` removes a key if a user supplied predicate evaluates to true for the value associated with the key. Crucially for the `WeakValueDictionary` use case, the predicate evaluation + deletion sequence is atomic, provided that the predicate doesn’t suspend. The predicate used by `WeakValueDictionary` includes a subtype check, which we must ensure doesn't suspend in free-threaded builds.
This commit is contained in:
parent
19c1dd60c5
commit
5d21d884b6
|
@ -2341,14 +2341,7 @@ is_subtype_with_mro(PyObject *a_mro, PyTypeObject *a, PyTypeObject *b)
|
||||||
int
|
int
|
||||||
PyType_IsSubtype(PyTypeObject *a, PyTypeObject *b)
|
PyType_IsSubtype(PyTypeObject *a, PyTypeObject *b)
|
||||||
{
|
{
|
||||||
#ifdef Py_GIL_DISABLED
|
return is_subtype_with_mro(a->tp_mro, a, b);
|
||||||
PyObject *mro = _PyType_GetMRO(a);
|
|
||||||
int res = is_subtype_with_mro(mro, a, b);
|
|
||||||
Py_XDECREF(mro);
|
|
||||||
return res;
|
|
||||||
#else
|
|
||||||
return is_subtype_with_mro(lookup_tp_mro(a), a, b);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Routines to do a method lookup in the type without looking in the
|
/* Routines to do a method lookup in the type without looking in the
|
||||||
|
|
Loading…
Reference in New Issue