This commit is contained in:
Charles-François Natali 2012-02-02 20:36:47 +01:00
commit 6dce7d633f
2 changed files with 26 additions and 1 deletions

View File

@ -635,6 +635,29 @@ class ThreadJoinOnShutdown(BaseTestCase):
output = "end of worker thread\nend of main thread\n" output = "end of worker thread\nend of main thread\n"
self.assertScriptHasOutput(script, output) self.assertScriptHasOutput(script, output)
@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): class ThreadingExceptionTests(BaseTestCase):
# A RuntimeError should be raised if Thread.start() is called # A RuntimeError should be raised if Thread.start() is called

View File

@ -976,10 +976,12 @@ void
PyOS_AfterFork(void) PyOS_AfterFork(void)
{ {
#ifdef WITH_THREAD #ifdef WITH_THREAD
/* PyThread_ReInitTLS() must be called early, to make sure that the TLS API
* can be called safely. */
PyThread_ReInitTLS();
PyEval_ReInitThreads(); PyEval_ReInitThreads();
main_thread = PyThread_get_thread_ident(); main_thread = PyThread_get_thread_ident();
main_pid = getpid(); main_pid = getpid();
_PyImport_ReInitLock(); _PyImport_ReInitLock();
PyThread_ReInitTLS();
#endif #endif
} }