mirror of
https://github.com/python/cpython.git
synced 2025-11-02 03:01:58 +00:00
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
This commit is contained in:
parent
e6b213ee3f
commit
5a1618a2c8
18 changed files with 439 additions and 126 deletions
|
|
@ -2511,9 +2511,9 @@ _collections__count_elements_impl(PyObject *module, PyObject *mapping,
|
|||
/* Only take the fast path when get() and __setitem__()
|
||||
* have not been overridden.
|
||||
*/
|
||||
mapping_get = _PyType_Lookup(Py_TYPE(mapping), &_Py_ID(get));
|
||||
mapping_get = _PyType_LookupRef(Py_TYPE(mapping), &_Py_ID(get));
|
||||
dict_get = _PyType_Lookup(&PyDict_Type, &_Py_ID(get));
|
||||
mapping_setitem = _PyType_Lookup(Py_TYPE(mapping), &_Py_ID(__setitem__));
|
||||
mapping_setitem = _PyType_LookupRef(Py_TYPE(mapping), &_Py_ID(__setitem__));
|
||||
dict_setitem = _PyType_Lookup(&PyDict_Type, &_Py_ID(__setitem__));
|
||||
|
||||
if (mapping_get != NULL && mapping_get == dict_get &&
|
||||
|
|
@ -2587,6 +2587,8 @@ _collections__count_elements_impl(PyObject *module, PyObject *mapping,
|
|||
}
|
||||
|
||||
done:
|
||||
Py_XDECREF(mapping_get);
|
||||
Py_XDECREF(mapping_setitem);
|
||||
Py_DECREF(it);
|
||||
Py_XDECREF(key);
|
||||
Py_XDECREF(newval);
|
||||
|
|
|
|||
|
|
@ -1096,7 +1096,7 @@ static int
|
|||
UnionType_setattro(PyObject *self, PyObject *key, PyObject *value)
|
||||
{
|
||||
/* XXX Should we disallow deleting _fields_? */
|
||||
if (-1 == PyObject_GenericSetAttr(self, key, value))
|
||||
if (-1 == PyType_Type.tp_setattro(self, key, value))
|
||||
return -1;
|
||||
|
||||
if (PyUnicode_Check(key) &&
|
||||
|
|
|
|||
|
|
@ -177,8 +177,7 @@ normalizeUserObj(PyObject *obj)
|
|||
PyObject *modname = fn->m_module;
|
||||
|
||||
if (name != NULL) {
|
||||
PyObject *mo = _PyType_Lookup(Py_TYPE(self), name);
|
||||
Py_XINCREF(mo);
|
||||
PyObject *mo = _PyType_LookupRef(Py_TYPE(self), name);
|
||||
Py_DECREF(name);
|
||||
if (mo != NULL) {
|
||||
PyObject *res = PyObject_Repr(mo);
|
||||
|
|
|
|||
|
|
@ -99,10 +99,11 @@ slot_tp_del(PyObject *self)
|
|||
return;
|
||||
}
|
||||
/* Execute __del__ method, if any. */
|
||||
del = _PyType_Lookup(Py_TYPE(self), tp_del);
|
||||
del = _PyType_LookupRef(Py_TYPE(self), tp_del);
|
||||
Py_DECREF(tp_del);
|
||||
if (del != NULL) {
|
||||
res = PyObject_CallOneArg(del, self);
|
||||
Py_DECREF(del);
|
||||
if (res == NULL)
|
||||
PyErr_WriteUnraisable(del);
|
||||
else
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue