summaryrefslogtreecommitdiffstats
path: root/Lib/multiprocessing/forkserver.py
diff options
context:
space:
mode:
authorAntoine Pitrou <pitrou@free.fr>2017-11-03 12:59:43 (GMT)
committerGitHub <noreply@github.com>2017-11-03 12:59:43 (GMT)
commit019c99f325287741d1e0eefeef2b75c8e00b884f (patch)
tree7bd7d25a44ffe1c6c1ee2d09d8845798cc622bf9 /Lib/multiprocessing/forkserver.py
parent5fbe5e161c969bc8a0d44a301152f8bf5afe0fc7 (diff)
downloadcpython-019c99f325287741d1e0eefeef2b75c8e00b884f.zip
cpython-019c99f325287741d1e0eefeef2b75c8e00b884f.tar.gz
cpython-019c99f325287741d1e0eefeef2b75c8e00b884f.tar.bz2
[3.6] bpo-31308: If multiprocessing's forkserver dies, launch it again when necessary (GH-3246) (#4252)
* bpo-31308: If multiprocessing's forkserver dies, launch it again when necessary. * Fix test on Windows * Add NEWS entry * Adopt a different approach: ignore SIGINT and SIGTERM, as in semaphore tracker. * Fix comment * Make sure the test doesn't muck with process state * Also test previously-started processes * Update 2017-08-30-17-59-36.bpo-31308.KbexyC.rst * Avoid masking SIGTERM in forkserver. It's not necessary and causes a race condition in test_many_processes.. (cherry picked from commit fc6b348b12ad401cab0261b7b71a65c60a08c0a8)
Diffstat (limited to 'Lib/multiprocessing/forkserver.py')
-rw-r--r--Lib/multiprocessing/forkserver.py21
1 files changed, 16 insertions, 5 deletions
diff --git a/Lib/multiprocessing/forkserver.py b/Lib/multiprocessing/forkserver.py
index d5ce625..fd19895 100644
--- a/Lib/multiprocessing/forkserver.py
+++ b/Lib/multiprocessing/forkserver.py
@@ -33,6 +33,7 @@ class ForkServer(object):
def __init__(self):
self._forkserver_address = None
self._forkserver_alive_fd = None
+ self._forkserver_pid = None
self._inherited_fds = None
self._lock = threading.Lock()
self._preload_modules = ['__main__']
@@ -89,8 +90,17 @@ class ForkServer(object):
'''
with self._lock:
semaphore_tracker.ensure_running()
- if self._forkserver_alive_fd is not None:
- return
+ if self._forkserver_pid is not None:
+ # forkserver was launched before, is it still running?
+ pid, status = os.waitpid(self._forkserver_pid, os.WNOHANG)
+ if not pid:
+ # still alive
+ return
+ # dead, launch it again
+ os.close(self._forkserver_alive_fd)
+ self._forkserver_address = None
+ self._forkserver_alive_fd = None
+ self._forkserver_pid = None
cmd = ('from multiprocessing.forkserver import main; ' +
'main(%d, %d, %r, **%r)')
@@ -127,6 +137,7 @@ class ForkServer(object):
os.close(alive_r)
self._forkserver_address = address
self._forkserver_alive_fd = alive_w
+ self._forkserver_pid = pid
#
#
@@ -149,11 +160,11 @@ def main(listener_fd, alive_r, preload, main_path=None, sys_path=None):
util._close_stdin()
- # ignoring SIGCHLD means no need to reap zombie processes;
- # letting SIGINT through avoids KeyboardInterrupt tracebacks
handlers = {
+ # no need to reap zombie processes;
signal.SIGCHLD: signal.SIG_IGN,
- signal.SIGINT: signal.SIG_DFL,
+ # protect the process from ^C
+ signal.SIGINT: signal.SIG_IGN,
}
old_handlers = {sig: signal.signal(sig, val)
for (sig, val) in handlers.items()}