summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAntoine Pitrou <solipsis@pitrou.net>2012-04-19 21:55:01 (GMT)
committerAntoine Pitrou <solipsis@pitrou.net>2012-04-19 21:55:01 (GMT)
commit52849bfaa384f1dcc26a8aa9092379921d835081 (patch)
treecf97e23e85810217b86808d64b5188288129fd6e
parentc45868ec697a70a80d1cf8a511894f073fda3a27 (diff)
downloadcpython-52849bfaa384f1dcc26a8aa9092379921d835081.zip
cpython-52849bfaa384f1dcc26a8aa9092379921d835081.tar.gz
cpython-52849bfaa384f1dcc26a8aa9092379921d835081.tar.bz2
Issue #14308: Fix an exception when a "dummy" thread is in the threading module's active list after a fork().
-rw-r--r--Lib/test/test_threading.py29
-rw-r--r--Lib/threading.py4
-rw-r--r--Misc/NEWS3
3 files changed, 36 insertions, 0 deletions
diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py
index 1a02ef2..ef04cd3 100644
--- a/Lib/test/test_threading.py
+++ b/Lib/test/test_threading.py
@@ -2,6 +2,8 @@
import test.test_support
from test.test_support import verbose
+from test.script_helper import assert_python_ok
+
import random
import re
import sys
@@ -414,6 +416,33 @@ class ThreadTests(BaseTestCase):
msg=('%d references still around' %
sys.getrefcount(weak_raising_cyclic_object())))
+ @unittest.skipUnless(hasattr(os, 'fork'), 'test needs fork()')
+ def test_dummy_thread_after_fork(self):
+ # Issue #14308: a dummy thread in the active list doesn't mess up
+ # the after-fork mechanism.
+ code = """if 1:
+ import thread, threading, os, time
+
+ def background_thread(evt):
+ # Creates and registers the _DummyThread instance
+ threading.current_thread()
+ evt.set()
+ time.sleep(10)
+
+ evt = threading.Event()
+ thread.start_new_thread(background_thread, (evt,))
+ evt.wait()
+ assert threading.active_count() == 2, threading.active_count()
+ if os.fork() == 0:
+ assert threading.active_count() == 1, threading.active_count()
+ os._exit(0)
+ else:
+ os.wait()
+ """
+ _, out, err = assert_python_ok("-c", code)
+ self.assertEqual(out, '')
+ self.assertEqual(err, '')
+
class ThreadJoinOnShutdown(BaseTestCase):
diff --git a/Lib/threading.py b/Lib/threading.py
index ff32dfb..2290855 100644
--- a/Lib/threading.py
+++ b/Lib/threading.py
@@ -605,6 +605,10 @@ class Thread(_Verbose):
pass
def __stop(self):
+ # DummyThreads delete self.__block, but they have no waiters to
+ # notify anyway (join() is forbidden on them).
+ if not hasattr(self, '_Thread__block'):
+ return
self.__block.acquire()
self.__stopped = True
self.__block.notify_all()
diff --git a/Misc/NEWS b/Misc/NEWS
index 6ae6e53..20ca968 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -50,6 +50,9 @@ Core and Builtins
Library
-------
+- Issue #14308: Fix an exception when a "dummy" thread is in the threading
+ module's active list after a fork().
+
- Issue #14538: HTMLParser can now parse correctly start tags that contain
a bare '/'.