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


http://hg.python.org/cpython/rev/ba54011aa295
changeset:   85462:ba54011aa295
branch:      2.7
parent:      85452:7d530381fc0e
user:        Charles-François Natali <cf.natali at gmail.com>
date:        Fri Aug 30 23:30:50 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 |  23 +++++++++++++++++++++++
  Lib/threading.py           |   2 +-
  Misc/ACKS                  |   1 +
  Misc/NEWS                  |   3 +++
  4 files changed, 28 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
@@ -443,6 +443,29 @@
         self.assertEqual(out, '')
         self.assertEqual(err, '')
 
+    @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.getcheckinterval()
+
+        # Make the bug more likely to manifest.
+        sys.setcheckinterval(10)
+
+        try:
+            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:
+                    t.join()
+                    pid, status = os.waitpid(pid, 0)
+                    self.assertEqual(0, status)
+        finally:
+            sys.setcheckinterval(old_interval)
+
 
 class ThreadJoinOnShutdown(BaseTestCase):
 
diff --git a/Lib/threading.py b/Lib/threading.py
--- a/Lib/threading.py
+++ b/Lib/threading.py
@@ -1220,7 +1220,7 @@
     new_active = {}
     current = current_thread()
     with _active_limbo_lock:
-        for thread in _active.itervalues():
+        for thread in _enumerate():
             # Any lock/condition variable may be currently locked or in an
             # invalid state, so we reinitialize them.
             if hasattr(thread, '_reset_internal_locks'):
diff --git a/Misc/ACKS b/Misc/ACKS
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -230,6 +230,7 @@
 Ben Darnell
 Kushal Das
 Jonathan Dasteel
+A. Jesse Jiryu Davis
 John DeGood
 Ned Deily
 Vincent Delft
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -32,6 +32,9 @@
 Library
 -------
 
+- Issue #18418: After fork(), reinit all threads states, not only active ones.
+  Patch by A. Jesse Jiryu Davis.
+
 - Issue #11973: Fix a problem in kevent. The flags and fflags fields are now
   properly handled as unsigned.
 

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


More information about the Python-checkins mailing list