aboutsummaryrefslogtreecommitdiff
path: root/rpkid/rpki/async.py
diff options
context:
space:
mode:
authorRob Austein <sra@hactrn.net>2011-09-10 01:03:58 +0000
committerRob Austein <sra@hactrn.net>2011-09-10 01:03:58 +0000
commit54658a14a0343acc04075cf042813151e3eaac01 (patch)
tree79f863a3a84f316bb301f6c2f76e179510d34a74 /rpkid/rpki/async.py
parent37db542b72729b195d847aa7a4aa2e72fc255368 (diff)
Check for exception select() throws on bad file descriptor, to avoid
going into a spin loop. (#69) Preserve old signal handlers even if we do have to restart the I/O loop. Minor clean up. svn path=/rpkid/rpki/async.py; revision=3976
Diffstat (limited to 'rpkid/rpki/async.py')
-rw-r--r--rpkid/rpki/async.py27
1 files changed, 19 insertions, 8 deletions
diff --git a/rpkid/rpki/async.py b/rpkid/rpki/async.py
index 9734ea41..2f0ea15f 100644
--- a/rpkid/rpki/async.py
+++ b/rpkid/rpki/async.py
@@ -281,11 +281,14 @@ def event_loop(catch_signals = (signal.SIGINT, signal.SIGTERM)):
"""
Replacement for asyncore.loop(), adding timer and signal support.
"""
+ old_signal_handlers = {}
while True:
- old_signal_handlers = {}
+ save_sigs = len(old_signal_handlers) == 0
try:
for sig in catch_signals:
- old_signal_handlers[sig] = signal.signal(sig, _raiseExitNow)
+ old = signal.signal(sig, _raiseExitNow)
+ if save_sigs:
+ old_signal_handlers[sig] = old
while asyncore.socket_map or deferred_queue or timer.queue:
run_deferred()
asyncore.poll(timer.seconds_until_wakeup(), asyncore.socket_map)
@@ -301,6 +304,15 @@ def event_loop(catch_signals = (signal.SIGINT, signal.SIGTERM)):
break
except SystemExit:
raise
+ except ValueError, e:
+ if str(e) == "filedescriptor out of range in select()":
+ rpki.log.error("Something is badly wrong, select() thinks we gave it a bad file descriptor.")
+ rpki.log.error("Content of asyncore.socket_map:")
+ for fd in sorted(asyncore.socket_map.iterkeys()):
+ rpki.log.error(" fd %s obj %r" % (fd, asyncore.socket_map[fd]))
+ rpki.log.error("Not safe to continue due to risk of spin loop on select(). Exiting.")
+ sys.exit(1)
+ rpki.log.error("event_loop() exited with exception %r, this is not supposed to happen, restarting" % e)
except Exception, e:
rpki.log.error("event_loop() exited with exception %r, this is not supposed to happen, restarting" % e)
else:
@@ -360,13 +372,12 @@ class sync_wrapper(object):
defer(thunk)
event_loop()
- if self.err is not None:
- if isinstance(self.err, tuple):
- raise self.err[0], self.err[1], self.err[2]
- else:
- raise self.err
- else:
+ if self.err is None:
return self.res
+ elif isinstance(self.err, tuple):
+ raise self.err[0], self.err[1], self.err[2]
+ else:
+ raise self.err
def exit_event_loop():
"""