https://github.com/python/cpython/commit/5d21d884b6ffa45dac50a5f9a07c41356a8478b4
commit: 5d21d884b6ffa45dac50a5f9a07c41356a8478b4
branch: main
author: mpage <[email protected]>
committer: colesbury <[email protected]>
date: 2024-03-29T13:42:02-04:00
summary:

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.

files:
M Objects/typeobject.c

diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 82822784aaf407..2ef79fbf17b329 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -2341,14 +2341,7 @@ is_subtype_with_mro(PyObject *a_mro, PyTypeObject *a, 
PyTypeObject *b)
 int
 PyType_IsSubtype(PyTypeObject *a, PyTypeObject *b)
 {
-#ifdef Py_GIL_DISABLED
-    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
+    return is_subtype_with_mro(a->tp_mro, a, b);
 }
 
 /* Routines to do a method lookup in the type without looking in the

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]

Reply via email to