diff -r 61d9c561b63d .idea/dictionaries/emptysquare.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.idea/dictionaries/emptysquare.xml Thu Jul 25 13:51:59 2013 -0400 @@ -0,0 +1,7 @@ + + + + ceval + + + \ No newline at end of file diff -r 61d9c561b63d Lib/test/test_threading.py --- a/Lib/test/test_threading.py Thu Jul 25 12:11:55 2013 -0400 +++ b/Lib/test/test_threading.py Thu Jul 25 13:51:59 2013 -0400 @@ -444,6 +444,27 @@ self.assertEqual(out, b'') self.assertEqual(err, b'') + @unittest.skipUnless(hasattr(os, 'fork'), "needs os.fork()") + def test_is_alive_after_fork(self): + # Try hard to trigger #18418: is_alive() could sometimes be True on + # threads that vanished after a fork. + + old_interval = sys.getswitchinterval() + self.addCleanup(sys.setswitchinterval, old_interval) + + # Make the bug more likely to manifest. + sys.setswitchinterval(1e-6) + + for i in range(20): + t = threading.Thread(target=lambda: None) + t.start() + pid = os.fork() + if pid == 0: + os._exit(1 if t.is_alive() else 0) + else: + (_, exit_status) = os.waitpid(pid, 0) + self.assertEqual(0, exit_status) + class ThreadJoinOnShutdown(BaseTestCase): diff -r 61d9c561b63d Lib/threading.py --- a/Lib/threading.py Thu Jul 25 12:11:55 2013 -0400 +++ b/Lib/threading.py Thu Jul 25 13:51:59 2013 -0400 @@ -1,5 +1,6 @@ """Thread module emulating a subset of Java's threading model.""" +import itertools import sys as _sys import _thread @@ -931,11 +932,13 @@ global _active_limbo_lock _active_limbo_lock = _allocate_lock() - # fork() only copied the current thread; clear references to others. + # fork() only copied the current thread; clear references to others, + # including any that were interrupted before moving themselves from + # _limbo to _active. new_active = {} current = current_thread() with _active_limbo_lock: - for thread in _active.values(): + for thread in itertools.chain(_active.values(), _limbo.values()): # Any lock/condition variable may be currently locked or in an # invalid state, so we reinitialize them. thread._reset_internal_locks()