summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavanum Srinivas <dims@linux.vnet.ibm.com>2012-12-27 12:22:56 -0500
committerDavanum Srinivas <dims@linux.vnet.ibm.com>2013-01-02 11:37:36 -0500
commitffeb0855085617095f19296770a1223cb5641d1c (patch)
treee332b2d402056fa039b0288e1e8b16cb9e831e70
parent8888ad0126f25c91b90f7bc4c2440da0bf35ec1d (diff)
downloadoslo-ffeb0855085617095f19296770a1223cb5641d1c.tar.gz
oslo-ffeb0855085617095f19296770a1223cb5641d1c.tar.xz
oslo-ffeb0855085617095f19296770a1223cb5641d1c.zip
Don't rely on os.wait() blocking
Before this fix which was included in eventlet 0.10.0: https://bitbucket.org/which_linden/eventlet/issue/92/eventletgreen-override-of-oswaitpid the os.wait() wrapper in eventlet would not block if no child processes had exited. This was clearly buggy behaviour and os.wait() no blocks correctly. However, it appears it now does not return if the parent process was interrupted by a signal. This means that you can't kill the parent process and have the child processes cleaned up gracefully. To avoid all these issues, switch to non-blocking wait behaviour. We use WNOHANG with waitpid() to poll for an exited child process and, if there is none, we yield to other green threads and sleep for a short period. This means excessive CPU usage, though, which will be tracked by bug #1095346. Check pid to avoid some unnecessary warning/info messages in the logs Fixes LP #1094076 Change-Id: I783fac652376c2daa9d591403b9f4c1fe9523043
-rw-r--r--openstack/common/service.py9
1 files changed, 8 insertions, 1 deletions
diff --git a/openstack/common/service.py b/openstack/common/service.py
index 0df0dec..740378f 100644
--- a/openstack/common/service.py
+++ b/openstack/common/service.py
@@ -243,7 +243,10 @@ class ProcessLauncher(object):
def _wait_child(self):
try:
- pid, status = os.wait()
+ # 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:
if exc.errno not in (errno.EINTR, errno.ECHILD):
raise
@@ -275,6 +278,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(.01)
continue
while self.running and len(wrap.children) < wrap.workers: