summaryrefslogtreecommitdiffstats
path: root/Lib/multiprocessing
diff options
context:
space:
mode:
authorAntoine Pitrou <pitrou@free.fr>2017-11-03 13:31:38 (GMT)
committerGitHub <noreply@github.com>2017-11-03 13:31:38 (GMT)
commitcbe1756e3ecefc0e24a5d0a4b8663db9b6d0cc52 (patch)
treeb8b7f15266c062c7e49adbbb3eb4bdd84b778199 /Lib/multiprocessing
parentfc6b348b12ad401cab0261b7b71a65c60a08c0a8 (diff)
downloadcpython-cbe1756e3ecefc0e24a5d0a4b8663db9b6d0cc52.zip
cpython-cbe1756e3ecefc0e24a5d0a4b8663db9b6d0cc52.tar.gz
cpython-cbe1756e3ecefc0e24a5d0a4b8663db9b6d0cc52.tar.bz2
bpo-31310: multiprocessing's semaphore tracker should be launched again if crashed (#3247)
* bpo-31310: multiprocessing's semaphore tracker should be launched again if crashed * Avoid mucking with process state in test. Add a warning if the semaphore process died, as semaphores may then be leaked. * Add NEWS entry
Diffstat (limited to 'Lib/multiprocessing')
-rw-r--r--Lib/multiprocessing/semaphore_tracker.py20
1 files changed, 17 insertions, 3 deletions
diff --git a/Lib/multiprocessing/semaphore_tracker.py b/Lib/multiprocessing/semaphore_tracker.py
index d5f259c..3e31bf8 100644
--- a/Lib/multiprocessing/semaphore_tracker.py
+++ b/Lib/multiprocessing/semaphore_tracker.py
@@ -29,6 +29,7 @@ class SemaphoreTracker(object):
def __init__(self):
self._lock = threading.Lock()
self._fd = None
+ self._pid = None
def getfd(self):
self.ensure_running()
@@ -40,8 +41,20 @@ class SemaphoreTracker(object):
This can be run from any process. Usually a child process will use
the semaphore created by its parent.'''
with self._lock:
- if self._fd is not None:
- return
+ if self._pid is not None:
+ # semaphore tracker was launched before, is it still running?
+ pid, status = os.waitpid(self._pid, os.WNOHANG)
+ if not pid:
+ # => still alive
+ return
+ # => dead, launch it again
+ os.close(self._fd)
+ self._fd = None
+ self._pid = None
+
+ warnings.warn('semaphore_tracker: process died unexpectedly, '
+ 'relaunching. Some semaphores might leak.')
+
fds_to_pass = []
try:
fds_to_pass.append(sys.stderr.fileno())
@@ -55,12 +68,13 @@ class SemaphoreTracker(object):
exe = spawn.get_executable()
args = [exe] + util._args_from_interpreter_flags()
args += ['-c', cmd % r]
- util.spawnv_passfds(exe, args, fds_to_pass)
+ pid = util.spawnv_passfds(exe, args, fds_to_pass)
except:
os.close(w)
raise
else:
self._fd = w
+ self._pid = pid
finally:
os.close(r)