gh-127266: avoid data races when updating type slots (gh-131174)

In the free-threaded build, avoid data races caused by updating type slots
or type flags after the type was initially created.  For those (typically
rare) cases, use the stop-the-world mechanism.  Remove the use of atomics
when reading or writing type flags.  The use of atomics is not sufficient to
avoid races (since flags are sometimes read without a lock and without
atomics) and are no longer required.
This commit is contained in:
Neil Schemenauer 2025-04-28 13:28:44 -07:00 committed by GitHub
parent 22f0730d40
commit e414a2d81c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 233 additions and 112 deletions

View file

@ -667,8 +667,11 @@ struct _Py_interp_cached_objects {
/* object.__reduce__ */
PyObject *objreduce;
#ifndef Py_GIL_DISABLED
/* resolve_slotdups() */
PyObject *type_slots_pname;
pytype_slotdef *type_slots_ptrs[MAX_EQUIV];
#endif
/* TypeVar and related types */
PyTypeObject *generic_type;

View file

@ -313,7 +313,7 @@ extern int _PyDict_CheckConsistency(PyObject *mp, int check_content);
// Fast inlined version of PyType_HasFeature()
static inline int
_PyType_HasFeature(PyTypeObject *type, unsigned long feature) {
return ((FT_ATOMIC_LOAD_ULONG_RELAXED(type->tp_flags) & feature) != 0);
return ((type->tp_flags) & feature) != 0;
}
extern void _PyType_InitCache(PyInterpreterState *interp);

View file

@ -134,7 +134,6 @@ extern int _PyType_AddMethod(PyTypeObject *, PyMethodDef *);
extern void _PyType_SetFlagsRecursive(PyTypeObject *self, unsigned long mask,
unsigned long flags);
extern unsigned int _PyType_GetVersionForCurrentState(PyTypeObject *tp);
PyAPI_FUNC(void) _PyType_SetVersion(PyTypeObject *tp, unsigned int version);
PyTypeObject *_PyType_LookupByVersion(unsigned int version);