summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCharles-François Natali <cf.natali@gmail.com>2013-08-30 21:34:26 (GMT)
committerCharles-François Natali <cf.natali@gmail.com>2013-08-30 21:34:26 (GMT)
commit79a53ea7d7d66f515b6bd4a38b1adbe8961a69f2 (patch)
tree1fad390e1918b6039c2cf2490d853614b52827ce
parentb586934f0eb69a3c04e1756abe9aa5a4ab307518 (diff)
parent9939cc89a4ee54ab50719a597a8b8a0795a691f6 (diff)
downloadcpython-79a53ea7d7d66f515b6bd4a38b1adbe8961a69f2.zip
cpython-79a53ea7d7d66f515b6bd4a38b1adbe8961a69f2.tar.gz
cpython-79a53ea7d7d66f515b6bd4a38b1adbe8961a69f2.tar.bz2
Issue #18418: After fork(), reinit all threads states, not only active ones.
Patch by A. Jesse Jiryu Davis.
-rw-r--r--Lib/test/test_threading.py21
-rw-r--r--Lib/threading.py2
-rw-r--r--Misc/ACKS1
-rw-r--r--Misc/NEWS3
4 files changed, 26 insertions, 1 deletions
diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py
index 3629749..0a78f8c 100644
--- a/Lib/test/test_threading.py
+++ b/Lib/test/test_threading.py
@@ -445,6 +445,27 @@ class ThreadTests(BaseTestCase):
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
index c7f919c..21bc781 100644
--- a/Lib/threading.py
+++ b/Lib/threading.py
@@ -940,7 +940,7 @@ def _after_fork():
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
index 1eaa897..a821cb9 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -288,6 +288,7 @@ Ben Darnell
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
index 0d7ba2f..dfba2ca 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -51,6 +51,9 @@ Core and Builtins
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.