summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrant Knudson <bknudson@us.ibm.com>2015-04-22 11:33:00 -0500
committerBrant Knudson <bknudson@us.ibm.com>2015-04-22 11:36:19 -0500
commit65a50eebb8d0a53a2c4c226eb9a564c4d535ac68 (patch)
treed776b664e945a70b37ecf4c7cc7782a1e0cba476
parent128dbdedd527de22d5e61a21d214b02a5af7b27c (diff)
downloadkeystone-65a50eebb8d0a53a2c4c226eb9a564c4d535ac68.tar.gz
Sync oslo-incubator Ie51669bd278288b768311ddf56ad31a2f28cc7ab
This syncs to oslo-incubator to commit 64b5819 and also includes 51280db. Change-Id: I7b43a67a0b67fe0ff5ac3d87708ecc4ab52102f8 Depends-On: Ie51669bd278288b768311ddf56ad31a2f28cc7ab Closes-Bug: #1446583 (cherry picked from commit 797da5f05444e7cfbf55df52867ade6107834f00)
-rw-r--r--keystone/openstack/common/service.py39
1 files changed, 29 insertions, 10 deletions
diff --git a/keystone/openstack/common/service.py b/keystone/openstack/common/service.py
index cfae56b74..d209b8e8e 100644
--- a/keystone/openstack/common/service.py
+++ b/keystone/openstack/common/service.py
@@ -199,18 +199,30 @@ class ServiceWrapper(object):
class ProcessLauncher(object):
- def __init__(self):
- """Constructor."""
+ _signal_handlers_set = set()
+
+ @classmethod
+ def _handle_class_signals(cls, *args, **kwargs):
+ for handler in cls._signal_handlers_set:
+ handler(*args, **kwargs)
+ 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()
def handle_signal(self):
- _set_signals_handler(self._handle_signal)
+ self._signal_handlers_set.add(self._handle_signal)
+ _set_signals_handler(self._handle_class_signals)
def _handle_signal(self, signo, frame):
self.sigcaught = signo
@@ -230,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
@@ -329,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:
@@ -359,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)
@@ -383,8 +396,14 @@ class ProcessLauncher(object):
if not _is_sighup_and_daemon(self.sigcaught):
break
+ cfg.CONF.reload_config_files()
+ for service in set(
+ [wrap.service for wrap in self.children.values()]):
+ service.reset()
+
for pid in self.children:
os.kill(pid, signal.SIGHUP)
+
self.running = True
self.sigcaught = None
except eventlet.greenlet.GreenletExit: