[Python-checkins] cpython (3.3): 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:40 CEST 2013


http://hg.python.org/cpython/rev/29fce7f31539
changeset:   85463:29fce7f31539
branch:      3.3
parent:      85456:9810844126e1
user:        Charles-François Natali <cf.natali at gmail.com>
date:        Fri Aug 30 23:32:53 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
@@ -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()
+            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
@@ -935,7 +935,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
@@ -279,6 +279,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
@@ -66,6 +66,9 @@
 Library
 -------
 
+- Issue #18418: After fork(), reinit all threads states, not only active ones.
+  Patch by A. Jesse Jiryu Davis.
+
 - Issue #16611: http.cookie now correctly parses the 'secure' and 'httponly'
   cookie flags.
 

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


More information about the Python-checkins mailing list