diff --git a/Lib/test/lock_tests.py b/Lib/test/lock_tests.py --- a/Lib/test/lock_tests.py +++ b/Lib/test/lock_tests.py @@ -2,6 +2,7 @@ Various tests for synchronization primitives. """ +import os import sys import time from _thread import start_new_thread, get_ident, TIMEOUT_MAX @@ -183,6 +184,27 @@ class BaseLockTests(BaseTestCase): self.assertFalse(results[0]) self.assertTimeout(results[1], 0.5) + @unittest.skipUnless(hasattr(os, 'fork'), + "test needs os.fork()") + def test_after_fork_different_thread(self): + # A lock taken from a different thread should be reinitialized + # in the child process. + lock = self.locktype() + def f(): + lock.acquire() + Bunch(f, 1).wait_for_finished() + pid = os.fork() + if pid == 0: + # Child + if lock.acquire(False): + # success + os._exit(0) + else: + # failure + os._exit(1) + pid, sts = os.waitpid(pid, 0) + self.assertEqual(sts, 0, "failed to re-acquire lock after fork") + class LockTests(BaseLockTests): """ @@ -229,6 +251,25 @@ class LockTests(BaseLockTests): self.assertFalse(lock.locked()) self.assertTrue(lock.acquire(blocking=False)) + @unittest.skipUnless(hasattr(os, 'fork'), + "test needs os.fork()") + def test_after_fork_same_thread(self): + # A lock taken from the current thread should stay taken in the + # child process. + lock = self.locktype() + lock.acquire() + pid = os.fork() + if pid == 0: + # Child + if not lock.acquire(False): + # success + os._exit(0) + else: + # failure + os._exit(1) + pid, sts = os.waitpid(pid, 0) + self.assertEqual(sts, 0, "re-acquire succeeded after fork") + class RLockTests(BaseLockTests): """ @@ -285,6 +326,26 @@ class RLockTests(BaseLockTests): lock.release() self.assertFalse(lock._is_owned()) + @unittest.skipUnless(hasattr(os, 'fork'), + "test needs os.fork()") + def test_after_fork_same_thread(self): + # A lock taken from the current thread should stay taken in the + # child process. + lock = self.locktype() + lock.acquire() + pid = os.fork() + if pid == 0: + # Child + try: + lock.release() + # success + os._exit(0) + except RuntimeError: + # failure + os._exit(1) + pid, sts = os.waitpid(pid, 0) + self.assertEqual(sts, 0, "release failed after fork") + class EventTests(BaseTestCase): """