From 95e5714be924f54f28c749b1df6cfec82f40e831 Mon Sep 17 00:00:00 2001 From: Marius Gedminas Date: Fri, 15 Apr 2016 11:10:11 +0300 Subject: [PATCH] Bugfix: notice programs that die too fast on Python 3.5 Background: Python 3.5 changes select.select() to handle EINTR internally (PEP 475). Our main loop used to rely on select() returning early when a SIGCHLD signal arrives, so this change broke our timing measurement logic and made a unit test fail on Python 3.5. I implemented one of the two suggested workarounds in the PEP: signal.set_wakeup_fd() (which is available since Python 2.6) will now tell our select() to wake up whenever a signal arrives. --- src/zdaemon/zdrun.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/zdaemon/zdrun.py b/src/zdaemon/zdrun.py index 33cd8b5..9488b31 100755 --- a/src/zdaemon/zdrun.py +++ b/src/zdaemon/zdrun.py @@ -380,6 +380,8 @@ def daemonize(self): proc = None # Subprocess instance def runforever(self): + sig_r, sig_w = os.pipe() + signal.set_wakeup_fd(sig_w) self.logger.info("daemon manager started") while self.should_be_up or self.proc.pid: if self.should_be_up and not self.proc.pid and not self.delay: @@ -389,7 +391,7 @@ def runforever(self): self.delay = time.time() + self.backofflimit if self.waitstatus: self.reportstatus() - r, w, x = [self.mastersocket], [], [] + r, w, x = [self.mastersocket, sig_r], [], [] if self.commandsocket: r.append(self.commandsocket) timeout = self.options.backofflimit @@ -422,6 +424,8 @@ def runforever(self): self.logger.exception("socket.error in doaccept(): %s" % str(msg)) self.commandsocket = None + if sig_r in r: + os.read(sig_r, 1) # don't let the buffer fill up self.logger.info("Exiting") sys.exit(0)