Skip to content

Commit

Permalink
Bugfix: notice programs that die too fast on Python 3.5
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
mgedmin committed Apr 15, 2016
1 parent 5d7dda4 commit 95e5714
Showing 1 changed file with 5 additions and 1 deletion.
6 changes: 5 additions & 1 deletion src/zdaemon/zdrun.py
Expand Up @@ -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:
Expand All @@ -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
Expand Down Expand Up @@ -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)

Expand Down

0 comments on commit 95e5714

Please sign in to comment.