From b0c03332489c86c1d5dc0c8dbc37fa202a378f3e Mon Sep 17 00:00:00 2001 From: benoitc Date: Tue, 10 May 2016 09:08:17 +0200 Subject: [PATCH] unblock the wait loop under python 3.5 in python 3.5 the select is blocking when waiting for it which prevent quick exit on SIGTERM. The problem is described: https://www.python.org/dev/peps/pep-0475/#backward-compatibility This change fix it by listening for signal event on the worker pipe. Once an event is triggered it will forcefully wake up the select and return. fix #1256 --- gunicorn/workers/base.py | 5 +++++ gunicorn/workers/sync.py | 5 ++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/gunicorn/workers/base.py b/gunicorn/workers/base.py index 94c2505fd..d187a611a 100644 --- a/gunicorn/workers/base.py +++ b/gunicorn/workers/base.py @@ -113,6 +113,8 @@ def changed(fname): [util.close_on_exec(s) for s in self.sockets] util.close_on_exec(self.tmp.fileno()) + self.wait_fds = self.sockets + [self.PIPE[0]] + self.log.close_on_exec() self.init_signals() @@ -164,6 +166,9 @@ def init_signals(self): signal.siginterrupt(signal.SIGTERM, False) signal.siginterrupt(signal.SIGUSR1, False) + if hasattr(signal, 'set_wakeup_fd'): + signal.set_wakeup_fd(self.PIPE[1]) + def handle_usr1(self, sig, frame): self.log.reopen_files() diff --git a/gunicorn/workers/sync.py b/gunicorn/workers/sync.py index 15ac08432..82943dec3 100644 --- a/gunicorn/workers/sync.py +++ b/gunicorn/workers/sync.py @@ -32,7 +32,7 @@ def accept(self, listener): def wait(self, timeout): try: self.notify() - ret = select.select(self.sockets, [], self.PIPE, timeout) + ret = select.select(self.wait_fds, [], [], timeout) if ret[0]: return ret[0] @@ -93,6 +93,9 @@ def run_for_multiple(self, timeout): if ready is not None: for listener in ready: + if listener == self.PIPE[0]: + continue + try: self.accept(listener) except EnvironmentError as e: