mirror of https://github.com/python/cpython
gh-125221: Fix free-threading data race in `object.__reduce_ex__` (#125267)
This commit is contained in:
parent
c1913effee
commit
b12e99261e
|
@ -0,0 +1,2 @@
|
||||||
|
Fix possible race condition when calling :meth:`~object.__reduce_ex__` for the
|
||||||
|
first time in the free threading build.
|
|
@ -2372,6 +2372,14 @@ _PyTypes_InitTypes(PyInterpreterState *interp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cache __reduce__ from PyBaseObject_Type object
|
||||||
|
PyObject *baseobj_dict = _PyType_GetDict(&PyBaseObject_Type);
|
||||||
|
PyObject *baseobj_reduce = PyDict_GetItemWithError(baseobj_dict, &_Py_ID(__reduce__));
|
||||||
|
if (baseobj_reduce == NULL && PyErr_Occurred()) {
|
||||||
|
return _PyStatus_ERR("Can't get __reduce__ from base object");
|
||||||
|
}
|
||||||
|
_Py_INTERP_CACHED_OBJECT(interp, objreduce) = baseobj_reduce;
|
||||||
|
|
||||||
// Must be after static types are initialized
|
// Must be after static types are initialized
|
||||||
if (_Py_initialize_generic(interp) < 0) {
|
if (_Py_initialize_generic(interp) < 0) {
|
||||||
return _PyStatus_ERR("Can't initialize generic types");
|
return _PyStatus_ERR("Can't initialize generic types");
|
||||||
|
|
|
@ -7359,18 +7359,7 @@ static PyObject *
|
||||||
object___reduce_ex___impl(PyObject *self, int protocol)
|
object___reduce_ex___impl(PyObject *self, int protocol)
|
||||||
/*[clinic end generated code: output=2e157766f6b50094 input=f326b43fb8a4c5ff]*/
|
/*[clinic end generated code: output=2e157766f6b50094 input=f326b43fb8a4c5ff]*/
|
||||||
{
|
{
|
||||||
#define objreduce \
|
PyObject *reduce;
|
||||||
(_Py_INTERP_CACHED_OBJECT(_PyInterpreterState_GET(), objreduce))
|
|
||||||
PyObject *reduce, *res;
|
|
||||||
|
|
||||||
if (objreduce == NULL) {
|
|
||||||
PyObject *dict = lookup_tp_dict(&PyBaseObject_Type);
|
|
||||||
objreduce = PyDict_GetItemWithError(dict, &_Py_ID(__reduce__));
|
|
||||||
if (objreduce == NULL && PyErr_Occurred()) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PyObject_GetOptionalAttr(self, &_Py_ID(__reduce__), &reduce) < 0) {
|
if (PyObject_GetOptionalAttr(self, &_Py_ID(__reduce__), &reduce) < 0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -7384,10 +7373,12 @@ object___reduce_ex___impl(PyObject *self, int protocol)
|
||||||
Py_DECREF(reduce);
|
Py_DECREF(reduce);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
override = (clsreduce != objreduce);
|
|
||||||
|
PyInterpreterState *interp = _PyInterpreterState_GET();
|
||||||
|
override = (clsreduce != _Py_INTERP_CACHED_OBJECT(interp, objreduce));
|
||||||
Py_DECREF(clsreduce);
|
Py_DECREF(clsreduce);
|
||||||
if (override) {
|
if (override) {
|
||||||
res = _PyObject_CallNoArgs(reduce);
|
PyObject *res = _PyObject_CallNoArgs(reduce);
|
||||||
Py_DECREF(reduce);
|
Py_DECREF(reduce);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -7396,7 +7387,6 @@ object___reduce_ex___impl(PyObject *self, int protocol)
|
||||||
}
|
}
|
||||||
|
|
||||||
return _common_reduce(self, protocol);
|
return _common_reduce(self, protocol);
|
||||||
#undef objreduce
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
|
Loading…
Reference in New Issue