diff options
author | Dino Viehland <dinoviehland@meta.com> | 2024-05-06 17:50:35 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-06 17:50:35 (GMT) |
commit | 5a1618a2c8c108b8c73aa9459b63f0dbd66b60f6 (patch) | |
tree | a9b79e4cb8e0a9d1d648e21619382a03363c1f46 /Objects/classobject.c | |
parent | e6b213ee3ffb05f067d30cb8bb45681887212444 (diff) | |
download | cpython-5a1618a2c8c108b8c73aa9459b63f0dbd66b60f6.zip cpython-5a1618a2c8c108b8c73aa9459b63f0dbd66b60f6.tar.gz cpython-5a1618a2c8c108b8c73aa9459b63f0dbd66b60f6.tar.bz2 |
gh-118362: Fix thread safety around lookups from the type cache in the face of concurrent mutators (#118454)
Add _PyType_LookupRef and use incref before setting attribute on type
Makes setting an attribute on a class and signaling type modified atomic
Avoid adding re-entrancy exposing the type cache in an inconsistent state by decrefing after type is updated
Diffstat (limited to 'Objects/classobject.c')
-rw-r--r-- | Objects/classobject.c | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/Objects/classobject.c b/Objects/classobject.c index 9cbb944..69a7d5f 100644 --- a/Objects/classobject.c +++ b/Objects/classobject.c @@ -188,15 +188,18 @@ method_getattro(PyObject *obj, PyObject *name) if (PyType_Ready(tp) < 0) return NULL; } - descr = _PyType_Lookup(tp, name); + descr = _PyType_LookupRef(tp, name); } if (descr != NULL) { descrgetfunc f = TP_DESCR_GET(Py_TYPE(descr)); - if (f != NULL) - return f(descr, obj, (PyObject *)Py_TYPE(obj)); + if (f != NULL) { + PyObject *res = f(descr, obj, (PyObject *)Py_TYPE(obj)); + Py_DECREF(descr); + return res; + } else { - return Py_NewRef(descr); + return descr; } } @@ -410,14 +413,17 @@ instancemethod_getattro(PyObject *self, PyObject *name) if (PyType_Ready(tp) < 0) return NULL; } - descr = _PyType_Lookup(tp, name); + descr = _PyType_LookupRef(tp, name); if (descr != NULL) { descrgetfunc f = TP_DESCR_GET(Py_TYPE(descr)); - if (f != NULL) - return f(descr, self, (PyObject *)Py_TYPE(self)); + if (f != NULL) { + PyObject *res = f(descr, self, (PyObject *)Py_TYPE(self)); + Py_DECREF(descr); + return res; + } else { - return Py_NewRef(descr); + return descr; } } |