Issue #13817: After fork(), reinit the ad-hoc TLS implementation earlier to fix
a random deadlock when fork() is called in a multithreaded process in debug mode, and make PyOS_AfterFork() more robust.
This commit is contained in:
parent
03c29f90c3
commit
6d0d24e359
|
@ -666,6 +666,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
|
||||
|
|
|
@ -991,11 +991,13 @@ 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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue