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
3+ import gc
14import threading
25import unittest
36
@@ -401,6 +404,41 @@ class B(A):
401404 with threading_helper .start_threads (threads ):
402405 pass
403406
407+ def test_abstractmethods_and_register (self ):
408+ # gh-156910: creating an ABC sets __abstractmethods__ and
409+ # Sequence.register() sets type flags recursively. Both stop the
410+ # world while holding the type lock. type_set_abstractmethods() did
411+ # not pin the type lock, so it could be released while waiting for
412+ # the stop-the-world mutex and then deadlock re-acquiring it. The
413+ # gc.collect() thread adds contention on the stop-the-world mutex,
414+ # which is needed to hit the deadlock.
415+ done = threading .Event ()
416+
417+ def make_abcs ():
418+ for _ in range (ITERS ):
419+ class C (abc .ABC ):
420+ @abc .abstractmethod
421+ def f (self ):
422+ pass
423+
424+ def register ():
425+ for _ in range (ITERS ):
426+ collections .abc .Sequence .register (type ("S" , (), {}))
427+
428+ def collect ():
429+ while not done .is_set ():
430+ gc .collect ()
431+
432+ workers = [Thread (target = make_abcs ) for _ in range (NTHREADS )]
433+ workers += [Thread (target = register ) for _ in range (NTHREADS )]
434+ collector = Thread (target = collect )
435+ with threading_helper .start_threads ([collector ]):
436+ try :
437+ with threading_helper .start_threads (workers ):
438+ pass
439+ finally :
440+ done .set ()
441+
404442 def test_class_creation_with_concurrent_setattr (self ):
405443 # Creating a class resolves its slots from the dicts along the MRO
406444 # 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