@@ -6066,27 +6066,14 @@ void
60666066_PyType_SetFlagsRecursive (PyTypeObject * self , unsigned long mask , unsigned long flags )
60676067{
60686068 BEGIN_TYPE_LOCK ();
6069- /* Ideally, changing flags and invalidating the old version tag would
6070- happen in one step. But type_modified_unlocked() is re-entrant and
6071- cannot run with the world stopped, so we must invalidate first.
6072- Immutable/static-builtin types are skipped because
6073- set_flags_recursive() does not modify them. */
6069+ /* Invalidate the old version first so
6070+ readers cannot assign a fresh tag from stale flags. */
60746071 if (!PyType_HasFeature (self , Py_TPFLAGS_IMMUTABLETYPE ) &&
60756072 (self -> tp_flags & mask ) != flags )
60766073 {
60776074 type_modified_unlocked (self );
6075+ set_flags_recursive (self , mask , flags );
60786076 }
6079- /* Keep TYPE_LOCK held while waiting for stop-the-world so no thread
6080- can reassign a version tag before the flag update. */
6081- type_lock_prevent_release ();
6082- types_stop_world ();
6083- /* Make TYPE_LOCK visible while mutating tp_flags. */
6084- type_lock_allow_release ();
6085- set_flags_recursive (self , mask , flags );
6086- /* Hide TYPE_LOCK again before restarting the world. */
6087- type_lock_prevent_release ();
6088- types_start_world ();
6089- type_lock_allow_release ();
60906077 END_TYPE_LOCK ();
60916078}
60926079
0 commit comments