mirror of
https://github.com/python/cpython.git
synced 2025-12-08 06:10:17 +00:00
[3.14] gh-133467: fix data race in type_set_name (GH-137302) (#137303)
gh-133467: fix data race in `type_set_name` (GH-137302)
Fix data race in `type_set_name` by assigning name under stop the world pause making it thread safe in free-threading.
(cherry picked from commit e99bc7fd44)
Co-authored-by: Kumar Aditya <kumaraditya@python.org>
This commit is contained in:
parent
070993b8ad
commit
bf397e272c
3 changed files with 22 additions and 4 deletions
|
|
@ -127,6 +127,20 @@ class ClassB(Base):
|
||||||
obj.__class__ = ClassB
|
obj.__class__ = ClassB
|
||||||
|
|
||||||
|
|
||||||
|
def test_name_change(self):
|
||||||
|
class Foo:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def writer():
|
||||||
|
for _ in range(1000):
|
||||||
|
Foo.__name__ = 'Bar'
|
||||||
|
|
||||||
|
def reader():
|
||||||
|
for _ in range(1000):
|
||||||
|
Foo.__name__
|
||||||
|
|
||||||
|
self.run_one(writer, reader)
|
||||||
|
|
||||||
def run_one(self, writer_func, reader_func):
|
def run_one(self, writer_func, reader_func):
|
||||||
barrier = threading.Barrier(NTHREADS)
|
barrier = threading.Barrier(NTHREADS)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1434,9 +1434,13 @@ type_set_name(PyObject *tp, PyObject *value, void *Py_UNUSED(closure))
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PyInterpreterState *interp = _PyInterpreterState_GET();
|
||||||
|
_PyEval_StopTheWorld(interp);
|
||||||
type->tp_name = tp_name;
|
type->tp_name = tp_name;
|
||||||
Py_SETREF(((PyHeapTypeObject*)type)->ht_name, Py_NewRef(value));
|
PyObject *old_name = ((PyHeapTypeObject*)type)->ht_name;
|
||||||
|
((PyHeapTypeObject*)type)->ht_name = Py_NewRef(value);
|
||||||
|
_PyEval_StartTheWorld(interp);
|
||||||
|
Py_DECREF(old_name);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -10406,9 +10410,11 @@ slot_tp_descr_get(PyObject *self, PyObject *obj, PyObject *type)
|
||||||
|
|
||||||
get = _PyType_LookupRef(tp, &_Py_ID(__get__));
|
get = _PyType_LookupRef(tp, &_Py_ID(__get__));
|
||||||
if (get == NULL) {
|
if (get == NULL) {
|
||||||
|
#ifndef Py_GIL_DISABLED
|
||||||
/* Avoid further slowdowns */
|
/* Avoid further slowdowns */
|
||||||
if (tp->tp_descr_get == slot_tp_descr_get)
|
if (tp->tp_descr_get == slot_tp_descr_get)
|
||||||
tp->tp_descr_get = NULL;
|
tp->tp_descr_get = NULL;
|
||||||
|
#endif
|
||||||
return Py_NewRef(self);
|
return Py_NewRef(self);
|
||||||
}
|
}
|
||||||
if (obj == NULL)
|
if (obj == NULL)
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,5 @@ race:PyObject_Realloc
|
||||||
|
|
||||||
# gh-133467. Some of these could be hard to trigger.
|
# gh-133467. Some of these could be hard to trigger.
|
||||||
race_top:update_one_slot
|
race_top:update_one_slot
|
||||||
race_top:slot_tp_descr_get
|
|
||||||
race_top:type_set_name
|
|
||||||
race_top:set_tp_bases
|
race_top:set_tp_bases
|
||||||
race_top:type_set_bases_unlocked
|
race_top:type_set_bases_unlocked
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue