@@ -3700,43 +3700,38 @@ mro_internal(PyTypeObject *type, int initial, PyObject **p_old_mro)
37003700 Don't let old_mro be GC'ed and its address be reused for
37013701 another object, like (suddenly!) a new tp_mro. */
37023702 old_mro = Py_XNewRef (lookup_tp_mro (type ));
3703- for (;;) {
3704- uint64_t gen = types_publish_gen ();
3705- new_mro = mro_invoke (type ); /* might cause reentrance */
3706- if (new_mro == NULL ) {
3707- Py_XDECREF (old_mro );
3708- return -1 ;
3709- }
3710- int res ;
3711- if (initial ) {
3712- // The type has not been revealed to other threads yet, so only
3713- // same-thread reentrance can have replaced tp_mro.
3714- if (lookup_tp_mro (type ) == old_mro ) {
3715- set_tp_mro (type , new_mro );
3716- res = 1 ;
3717- }
3718- else {
3719- res = 0 ;
3720- }
3703+ new_mro = mro_invoke (type ); /* might cause reentrance */
3704+ if (new_mro == NULL ) {
3705+ Py_XDECREF (old_mro );
3706+ return -1 ;
3707+ }
3708+ int res ;
3709+ if (initial ) {
3710+ // The type has not been revealed to other threads yet, so only
3711+ // same-thread reentrance can have replaced tp_mro.
3712+ if (lookup_tp_mro (type ) == old_mro ) {
3713+ set_tp_mro (type , new_mro );
3714+ res = 1 ;
37213715 }
37223716 else {
3723- // Store with the world stopped. TYPE_LOCK may have been
3724- // released while mro_invoke() ran or while waiting to stop the
3725- // world, so check for reentrance and for concurrent mutation of
3726- // the hierarchy inside the stop-the-world.
3727- res = try_set_tp_mro (type , old_mro , new_mro , gen );
3728- }
3729- if (res == 1 ) {
3730- break ;
3717+ res = 0 ;
37313718 }
3719+ }
3720+ else {
3721+ // Store with the world stopped. TYPE_LOCK may have been released
3722+ // while mro_invoke() ran, so check for reentrance inside the
3723+ // stop-the-world. The publish generation is deliberately not
3724+ // checked: mro() can itself update types (assign a slot, for
3725+ // example) and the result is stored anyway, as on the default
3726+ // build.
3727+ res = try_set_tp_mro (type , old_mro , new_mro , TYPES_PUBLISH_GEN_NONE );
3728+ assert (res != -1 );
3729+ }
3730+ if (res == 0 ) {
3731+ /* reentrance: tp_mro was replaced by someone else */
37323732 Py_DECREF (new_mro );
3733- if (res == 0 ) {
3734- /* reentrance: tp_mro was replaced by someone else */
3735- Py_XDECREF (old_mro );
3736- return 0 ;
3737- }
3738- /* stale: another thread changed the hierarchy, compute again */
3739- assert (res == -1 );
3733+ Py_XDECREF (old_mro );
3734+ return 0 ;
37403735 }
37413736 /* Drop our temporary reference. The reference previously owned by
37423737 the type is now owned by this function and transferred below. */
0 commit comments