diff options
author | Charles-François Natali <neologix@free.fr> | 2012-02-02 19:38:10 (GMT) |
---|---|---|
committer | Charles-François Natali <neologix@free.fr> | 2012-02-02 19:38:10 (GMT) |
commit | 3f32fc87adfa5e14ee24c8dc94e629e74283d1ca (patch) | |
tree | 23f3c9cf35f01d95bd5b16e7f72a15f7afa11108 | |
parent | 4b0eab62f04fc2e738b1bff1d170c7f6f96c1920 (diff) | |
parent | 227e377b36378d4cc86c3dd182f8d7c031e41f86 (diff) | |
download | cpython-3f32fc87adfa5e14ee24c8dc94e629e74283d1ca.zip cpython-3f32fc87adfa5e14ee24c8dc94e629e74283d1ca.tar.gz cpython-3f32fc87adfa5e14ee24c8dc94e629e74283d1ca.tar.bz2 |
Merge.
-rw-r--r-- | Lib/test/test_threading.py | 23 | ||||
-rw-r--r-- | Modules/signalmodule.c | 4 |
2 files changed, 26 insertions, 1 deletions
diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py index de29afa..77c4ca4 100644 --- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py @@ -674,6 +674,29 @@ class ThreadJoinOnShutdown(BaseTestCase): rc, out, err = assert_python_ok('-c', script) self.assertFalse(err) + @unittest.skipUnless(hasattr(os, 'fork'), "needs os.fork()") + def test_reinit_tls_after_fork(self): + # Issue #13817: fork() would deadlock in a multithreaded program with + # the ad-hoc TLS implementation. + + def do_fork_and_wait(): + # just fork a child process and wait it + pid = os.fork() + if pid > 0: + os.waitpid(pid, 0) + else: + os._exit(0) + + # start a bunch of threads that will fork() child processes + threads = [] + for i in range(16): + t = threading.Thread(target=do_fork_and_wait) + threads.append(t) + t.start() + + for t in threads: + t.join() + class ThreadingExceptionTests(BaseTestCase): # A RuntimeError should be raised if Thread.start() is called diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index c28f7af..e46f8cf 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -1403,12 +1403,14 @@ void PyOS_AfterFork(void) { #ifdef WITH_THREAD + /* PyThread_ReInitTLS() must be called early, to make sure that the TLS API + * can be called safely. */ + PyThread_ReInitTLS(); _PyGILState_Reinit(); PyEval_ReInitThreads(); main_thread = PyThread_get_thread_ident(); main_pid = getpid(); _PyImport_ReInitLock(); - PyThread_ReInitTLS(); #endif } |