File tree Expand file tree Collapse file tree
Lib/test/test_free_threading Expand file tree Collapse file tree Original file line number Diff line number Diff line change 1+ import abc
2+ import collections .abc
13import gc
24import threading
35import unittest
@@ -569,6 +571,40 @@ def subsetter():
569571 self .assertIn (C , A .__subclasses__ ())
570572 self .assertNotIn (C , B .__subclasses__ ())
571573
574+ def test_abstractmethods_and_register (self ):
575+ # gh-156910: creating an ABC sets __abstractmethods__ and
576+ # Sequence.register() sets type flags recursively. Both take the type
577+ # lock and stop the world, and racing them used to deadlock between
578+ # the type lock and the stop-the-world mutex. The gc.collect() thread
579+ # adds contention on the stop-the-world mutex, which is needed to hit
580+ # the deadlock.
581+ done = threading .Event ()
582+
583+ def make_abcs ():
584+ for _ in range (ITERS ):
585+ class C (abc .ABC ):
586+ @abc .abstractmethod
587+ def f (self ):
588+ pass
589+
590+ def register ():
591+ for _ in range (ITERS ):
592+ collections .abc .Sequence .register (type ("S" , (), {}))
593+
594+ def collect ():
595+ while not done .is_set ():
596+ gc .collect ()
597+
598+ workers = [Thread (target = make_abcs ) for _ in range (NTHREADS )]
599+ workers += [Thread (target = register ) for _ in range (NTHREADS )]
600+ collector = Thread (target = collect )
601+ with threading_helper .start_threads ([collector ]):
602+ try :
603+ with threading_helper .start_threads (workers ):
604+ pass
605+ finally :
606+ done .set ()
607+
572608 def test_class_creation_with_concurrent_setattr (self ):
573609 # Creating a class resolves its slots from the dicts along the MRO
574610 # while holding the type lock, before the class is reachable from
Original file line number Diff line number Diff line change 1+ Add a free-threading regression test for the deadlock between creating an
2+ abstract base class and :meth: `ABCMeta.register <abc.ABCMeta.register> `.
You can’t perform that action at this time.
0 commit comments