[Python-checkins] cpython (merge 3.3 -> default): Issue #18418: After fork(), reinit all threads states, not only active ones.

charles-francois.natali python-checkins at python.org
Fri Aug 30 23:34:42 CEST 2013


http://hg.python.org/cpython/rev/8f39e2f987fb
changeset:   85464:8f39e2f987fb
parent:      85461:8fd72b1bb262
parent:      85463:29fce7f31539
user:        Charles-François Natali <cf.natali at gmail.com>
date:        Fri Aug 30 23:34:26 2013 +0200
summary:
  Issue #18418: After fork(), reinit all threads states, not only active ones.
Patch by A. Jesse Jiryu Davis.

files:
  Lib/test/test_threading.py |  21 +++++++++++++++++++++
  Lib/threading.py           |   2 +-
  Misc/ACKS                  |   1 +
  Misc/NEWS                  |   3 +++
  4 files changed, 26 insertions(+), 1 deletions(-)


diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py
--- a/Lib/test/test_threading.py
+++ b/Lib/test/test_threading.py
@@ -445,6 +445,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()
+            self.addCleanup(t.join)
+            pid = os.fork()
+            if pid == 0:
+                os._exit(1 if t.is_alive() else 0)
+            else:
+                pid, status = os.waitpid(pid, 0)
+                self.assertEqual(0, status)
+
 
 class ThreadJoinOnShutdown(BaseTestCase):
 
diff --git a/Lib/threading.py b/Lib/threading.py
--- a/Lib/threading.py
+++ b/Lib/threading.py
@@ -940,7 +940,7 @@
     new_active = {}
     current = current_thread()
     with _active_limbo_lock:
-        for thread in _active.values():
+        for thread in _enumerate():
             # Any lock/condition variable may be currently locked or in an
             # invalid state, so we reinitialize them.
             thread._reset_internal_locks()
diff --git a/Misc/ACKS b/Misc/ACKS
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -288,6 +288,7 @@
 Kushal Das
 Jonathan Dasteel
 Pierre-Yves David
+A. Jesse Jiryu Davis
 John DeGood
 Ned Deily
 Vincent Delft
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -51,6 +51,9 @@
 Library
 -------
 
+- Issue #18418: After fork(), reinit all threads states, not only active ones.
+  Patch by A. Jesse Jiryu Davis.
+
 - Issue #17974: Switch unittest from using getopt to using argparse.
 
 - Issue #11798: TestSuite now drops references to own tests after execution.

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list