From ac8abbe4482b8da0c0296ba6ccca9aca4d8432f0 Mon Sep 17 00:00:00 2001 From: Benoit Chesneau Date: Sun, 10 Jan 2010 15:13:42 +0100 Subject: [PATCH] trap SIGCHLD and wake up master. fix issue 3. HUP isn't correctly handled yet on master. --- gunicorn/arbiter.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/gunicorn/arbiter.py b/gunicorn/arbiter.py index a5f6c53d..c7861594 100644 --- a/gunicorn/arbiter.py +++ b/gunicorn/arbiter.py @@ -49,7 +49,7 @@ class Arbiter(object): SIG_QUEUE = [] SIGNALS = map( lambda x: getattr(signal, "SIG%s" % x), - "QUIT INT TERM TTIN TTOU".split() + "CHLD QUIT INT TERM TTIN TTOU".split() ) SIG_NAMES = dict( (getattr(signal, name), name[3:].lower()) for name in dir(signal) @@ -156,7 +156,10 @@ class Arbiter(object): log.info("Master is shutting down.") self.stop() - + + def handle_chld(self): + self.wakeup() + def handle_quit(self): self.stop(False) raise StopIteration @@ -176,6 +179,15 @@ class Arbiter(object): if self.num_workers > 0: self.num_workers -= 1 + def wakeup(self): + while True: + try: + os.write(self.PIPE[1], ".") + return + except OSError, e: + if e[0] not in [errno.EAGAIN, errno.EINTR]: + raise + def sleep(self): try: ready = select.select([self.PIPE[0]], [], [], 1) @@ -205,8 +217,7 @@ class Arbiter(object): self.kill_workers(signal.SIGKILL) def murder_workers(self): - running_workers = tuple(self.WORKERS.iteritems()) - for (pid, worker) in running_workers: + for (pid, worker) in list(self.WORKERS.items()): diff = time.time() - os.fstat(worker.tmp.fileno()).st_mtime if diff < self.timeout: continue