@@ -3431,13 +3431,43 @@ def test_noforkbomb(self):
34313431 self .assertEqual ('123' , out .decode ('ascii' ).rstrip ())
34323432 self .assertEqual ('' , err .decode ('ascii' ))
34333433
3434+ #
3435+ # Issue #17555: ForkAwareThreadLock
3436+ #
3437+
3438+ class TestForkAwareThreadLock (unittest .TestCase ):
3439+ # We recurisvely start processes. Issue #17555 meant that the
3440+ # after fork registry would get duplicate entries for the same
3441+ # lock. The size of the registry at generation n was ~2**n.
3442+
3443+ @classmethod
3444+ def child (cls , n , conn ):
3445+ if n > 1 :
3446+ p = multiprocessing .Process (target = cls .child , args = (n - 1 , conn ))
3447+ p .start ()
3448+ p .join ()
3449+ else :
3450+ conn .send (len (util ._afterfork_registry ))
3451+ conn .close ()
3452+
3453+ def test_lock (self ):
3454+ r , w = multiprocessing .Pipe (False )
3455+ l = util .ForkAwareThreadLock ()
3456+ old_size = len (util ._afterfork_registry )
3457+ p = multiprocessing .Process (target = self .child , args = (5 , w ))
3458+ p .start ()
3459+ new_size = r .recv ()
3460+ p .join ()
3461+ self .assertLessEqual (new_size , old_size )
3462+
34343463#
34353464#
34363465#
34373466
34383467testcases_other = [OtherTest , TestInvalidHandle , TestInitializers ,
34393468 TestStdinBadfiledescriptor , TestWait , TestInvalidFamily ,
3440- TestFlags , TestTimeouts , TestNoForkBomb ]
3469+ TestFlags , TestTimeouts , TestNoForkBomb ,
3470+ TestForkAwareThreadLock ]
34413471
34423472#
34433473#
0 commit comments