def _run_once(self): """Run one iteration of the event handler.""" stats.increment("chiral.net.netcore.select_calls") delay = self.time_to_next_event() if delay is None and len(self._read_sockets) == 0 and len(self._write_sockets) == 0: return False try: rlist, wlist = select.select( self._read_sockets.keys(), self._write_sockets.keys(), (), delay )[:2] except KeyboardInterrupt: # Just return. return False def _handle_events(items, event_list): """ For each item in items: resume the coroutine in event_list whose key is that item. key is that item. """ for key in items: if key not in event_list: continue coro = event_list[key] del event_list[key] # Yes, we really do want to catch /all/ Exceptions # pylint: disable-msg=W0703 try: coro.resume(None) except Exception: print "Unhandled exception in TCP event %s:" % (coro, ) traceback.print_exc() _handle_events(rlist, self._read_sockets) _handle_events(wlist, self._write_sockets) self._handle_scheduled_events() return True
def run(self): """Run the main event processing loop.""" # Because this is the main event processing loop, it cannot # be replaced when the module is reloaded. Therefore, as # little logic as possible should happen here. while True: stats.increment("chiral.net.netcore.%s.loops" % self.__class__.__name__) res = self._run_once() if not res: break close_list = list(self._close_list.itervalues()) for sock in close_list: sock.close()