sync oslo: service child process normal SIGTERM exit
service.py had some code where the child process would catch the
SIGTERM from the parent just so it could exit with 1 status rather
than with an indication that it exited due to SIGTERM. When
shutting down the parent doesn't care in what way the child ended,
only that they're all gone, so this code is unnecessary.
Also, for some reason this caused the child to never exit while
there was an open connection from a client. Probably something
with eventlet and signal handling.
Syncs commit: 702bc569987854b602ef189655c201c348de84cb
Change-Id: I3c5249f5e59bb396bcb50964907ea61ebb2a3c8a
Closes-Bug: #1446583
(cherry picked from commit f0f158af37)
This commit is contained in:
@@ -206,12 +206,16 @@ class ProcessLauncher(object):
|
||||
for handler in cls._signal_handlers_set:
|
||||
handler(*args, **kwargs)
|
||||
|
||||
def __init__(self):
|
||||
"""Constructor."""
|
||||
def __init__(self, wait_interval=0.01):
|
||||
"""Constructor.
|
||||
|
||||
:param wait_interval: The interval to sleep for between checks
|
||||
of child process exit.
|
||||
"""
|
||||
self.children = {}
|
||||
self.sigcaught = None
|
||||
self.running = True
|
||||
self.wait_interval = wait_interval
|
||||
rfd, self.writepipe = os.pipe()
|
||||
self.readpipe = eventlet.greenio.GreenPipe(rfd, 'r')
|
||||
self.handle_signal()
|
||||
@@ -238,15 +242,12 @@ class ProcessLauncher(object):
|
||||
|
||||
def _child_process_handle_signal(self):
|
||||
# Setup child signal handlers differently
|
||||
def _sigterm(*args):
|
||||
signal.signal(signal.SIGTERM, signal.SIG_DFL)
|
||||
raise SignalExit(signal.SIGTERM)
|
||||
|
||||
def _sighup(*args):
|
||||
signal.signal(signal.SIGHUP, signal.SIG_DFL)
|
||||
raise SignalExit(signal.SIGHUP)
|
||||
|
||||
signal.signal(signal.SIGTERM, _sigterm)
|
||||
# Parent signals with SIGTERM when it wants us to go away.
|
||||
signal.signal(signal.SIGTERM, signal.SIG_DFL)
|
||||
if _sighup_supported():
|
||||
signal.signal(signal.SIGHUP, _sighup)
|
||||
# Block SIGINT and let the parent send us a SIGTERM
|
||||
@@ -337,8 +338,8 @@ class ProcessLauncher(object):
|
||||
|
||||
def _wait_child(self):
|
||||
try:
|
||||
# Block while any of child processes have exited
|
||||
pid, status = os.waitpid(0, 0)
|
||||
# Don't block if no child processes have exited
|
||||
pid, status = os.waitpid(0, os.WNOHANG)
|
||||
if not pid:
|
||||
return None
|
||||
except OSError as exc:
|
||||
@@ -367,6 +368,10 @@ class ProcessLauncher(object):
|
||||
while self.running:
|
||||
wrap = self._wait_child()
|
||||
if not wrap:
|
||||
# Yield to other threads if no children have exited
|
||||
# Sleep for a short time to avoid excessive CPU usage
|
||||
# (see bug #1095346)
|
||||
eventlet.greenthread.sleep(self.wait_interval)
|
||||
continue
|
||||
while self.running and len(wrap.children) < wrap.workers:
|
||||
self._start_child(wrap)
|
||||
|
||||
Reference in New Issue
Block a user