def fire_timers(self, when): debug_blocking = self.debug_blocking timers = self.timers while timers: # current evaluated exp, t = timers[0] if t.called: # remove called/cancelled timer heappop(timers) continue due = exp - when # self.clock() if due > 0: return self.timer_delay += due # delay is negative value self.timer_delay /= 2 # remove evaluated event heappop(timers) if debug_blocking: self.block_detect_pre() try: t() except self.SYSTEM_EXCEPTIONS: raise except: if self.debug_exceptions: self.squelch_generic_exception(sys.exc_info()) support.clear_sys_exc_info() if debug_blocking: self.block_detect_post()
def fire_timers(self, when): t = self.timers heappop = heapq.heappop while t: next = t[0] exp = next[0] timer = next[2] if when < exp: break heappop(t) try: try: timer() except self.SYSTEM_EXCEPTIONS: raise except: self.squelch_timer_exception(timer, sys.exc_info()) clear_sys_exc_info() finally: self.timer_finished(timer)
def fire_timers(self, when): t = self.timers heappop = heapq.heappop heappush = heapq.heappush while t: next = t[0] exp = next[0] timer = next[1] if when < exp: break heappop(t) try: if timer.called: self.timers_canceled -= 1 else: # if idleness timer add active time to timeout if timer.idleness: exp += timer.greenlet.active_clock - timer.active_clock timer.active_clock = timer.greenlet.active_clock if when < exp: heappush(exp, timer) continue timer() except self.SYSTEM_EXCEPTIONS: raise except: self.squelch_timer_exception(timer, sys.exc_info()) clear_sys_exc_info()
def wait(self, seconds=None): readers = self.listeners[READ] writers = self.listeners[WRITE] if not readers and not writers: if seconds: time.sleep(seconds) return all_fds = list(readers) + list(writers) try: r, w, er = select.select(readers.keys(), writers.keys(), all_fds, seconds) except select.error as e: if get_errno(e) == errno.EINTR: return elif get_errno(e) in BAD_SOCK: self._remove_bad_fds() return else: raise for fileno in er: readers.get(fileno, noop).cb(fileno) writers.get(fileno, noop).cb(fileno) for listeners, events in ((readers, r), (writers, w)): for fileno in events: try: listeners.get(fileno, noop).cb(fileno) except self.SYSTEM_EXCEPTIONS: raise except: self.squelch_exception(fileno, sys.exc_info()) clear_sys_exc_info()
def fire_timers(self, when): t = self.timers heappop = heapq.heappop while t: next = t[0] exp = next[0] timer = next[1] if when < exp: break heappop(t) try: if timer.called: self.timers_canceled -= 1 else: timer() except self.SYSTEM_EXCEPTIONS: raise except: self.squelch_timer_exception(timer, sys.exc_info()) clear_sys_exc_info()
def wait(self, seconds=None): readers = self.listeners[self.READ] writers = self.listeners[self.WRITE] if not readers and not writers: if seconds: time.sleep(seconds) return reader_fds = list(readers) writer_fds = list(writers) all_fds = reader_fds + writer_fds try: r, w, er = select.select(reader_fds, writer_fds, all_fds, seconds) except select.error as e: if support.get_errno(e) == errno.EINTR: return elif support.get_errno(e) in BAD_SOCK: self._remove_bad_fds() return else: raise for fileno in er: readers.get(fileno, hub.noop).cb(fileno) writers.get(fileno, hub.noop).cb(fileno) for listeners, events in ((readers, r), (writers, w)): for fileno in events: try: listeners.get(fileno, hub.noop).cb(fileno) except self.SYSTEM_EXCEPTIONS: raise except: self.squelch_exception(fileno, sys.exc_info()) support.clear_sys_exc_info()
def done(): self.timer_canceled(timer) try: timer() except: traceback.print_exc() clear_sys_exc_info()
def wrapper(): try: func(**v) except (GreenletExit, weakref.ReferenceError): clear_sys_exc_info() except: logger.exception("an unexpected exception occured.") clear_sys_exc_info()
def wrapper(): try: func(**v) except (GreenletExit, ReferenceError): clear_sys_exc_info() except: logger.exception("an unexpected exception occured.") clear_sys_exc_info()
def wrapper_notbound(): try: func(*args, **kwargs) except GreenletExit: clear_sys_exc_info() except: logger.exception("an unexpected exception occured.") clear_sys_exc_info()
def wrapper_bound(): try: func(func_self, *args, **kwargs) except (GreenletExit, weakref.ReferenceError): clear_sys_exc_info() except: logger.exception("an unexpected exception occured.") clear_sys_exc_info()
def wrapper_bound(): try: func(func_self, *args, **kwargs) except (GreenletExit, ReferenceError): clear_sys_exc_info() except: logger.exception("an unexpected exception occured.") clear_sys_exc_info()
def run_and_check(run_client): w = run_interaction(run_client=run_client) clear_sys_exc_info() if w(): print pformat(gc.get_referrers(w())) for x in gc.get_referrers(w()): print pformat(x) for y in gc.get_referrers(x): print '-', pformat(y) raise AssertionError('server should be dead by now')
def wait(self, seconds=None): readers = self.listeners[self.READ] writers = self.listeners[self.WRITE] if not readers and not writers: if seconds: time.sleep(seconds) return try: presult = self.do_poll(seconds) except (IOError, select.error) as e: if support.get_errno(e) == errno.EINTR: return raise SYSTEM_EXCEPTIONS = self.SYSTEM_EXCEPTIONS if self.debug_blocking: self.block_detect_pre() # Accumulate the listeners to call back to prior to # triggering any of them. This is to keep the set # of callbacks in sync with the events we've just # polled for. It prevents one handler from invalidating # another. callbacks = set() noop = hub.noop # shave getattr for fileno, event in presult: if event & self.READ_MASK: callbacks.add((readers.get(fileno, noop), fileno)) if event & self.WRITE_MASK: callbacks.add((writers.get(fileno, noop), fileno)) if event & select.POLLNVAL: self.remove_descriptor(fileno) continue if event & self.EXC_MASK: callbacks.add((readers.get(fileno, noop), fileno)) callbacks.add((writers.get(fileno, noop), fileno)) for listener, fileno in callbacks: try: listener.cb(fileno) except SYSTEM_EXCEPTIONS: raise except: self.squelch_exception(fileno, sys.exc_info()) support.clear_sys_exc_info() if self.debug_blocking: self.block_detect_post()
def callMethodInEventLoop(func, *args, **kwargs): if not get_hub().running or getcurrent() is get_hub().greenlet: return func(*args, **kwargs) done = Event() def wrapper(): assert getcurrent() is get_hub().greenlet try: result = func(*args, **kwargs) done.send(result) except Exception as e: done.send_exception(e) clear_sys_exc_info() QTimer.singleShot(0, wrapper) return done.wait()
def switch(self): cur = greenlet.getcurrent() assert cur is not self.greenlet, 'Cannot switch to MAINLOOP from MAINLOOP' switch_out = getattr(cur, 'switch_out', None) if switch_out is not None: try: switch_out() except: self.squelch_generic_exception(sys.exc_info()) self.ensure_greenlet() try: if self.greenlet.parent is not cur: cur.parent = self.greenlet except ValueError: pass # gets raised if there is a greenlet parent cycle clear_sys_exc_info() return self.greenlet.switch()
def _killall_helper(greenlets): for ref, name in greenlets: greenlet = ref() if greenlet is None: continue try: greenlet.kill() if greenlet: try: greenlet.wait() except: logger.info("There are some error occured in greenlet.") clear_sys_exc_info() except: clear_sys_exc_info() del greenlets[:] gc.collect()
def remove_descriptor(self, fileno): """ Completely remove all listeners for this fileno. For internal use only.""" for evtype in EVENT_TYPES: for l in [self.listeners[evtype].pop(fileno, None)]+self.secondaries[evtype].pop(fileno, []): if l is None: continue try: l.cb(fileno) except: self.squelch_exception(fileno, sys.exc_info()) clear_sys_exc_info() try: self.poll.unregister(fileno) except (KeyError, ValueError, IOError, OSError): # raised if we try to remove a fileno that was # already removed/invalid pass
def pollwait(self, seconds=None): readers = self.listeners[READ] writers = self.listeners[WRITE] SYSTEM_EXCEPTIONS = self.SYSTEM_EXCEPTIONS if not readers and not writers: if seconds: sleep(seconds) return while True: try: presult = self.do_poll(seconds) except (IOError, select.error), e: if get_errno(e) == errno.EINTR: seconds = 0 continue raise if len(presult) == 0: return if self.debug_blocking: self.block_detect_pre() for fileno, event in presult: try: if event & READ_MASK: readers.get(fileno, noop).cb(fileno) if event & WRITE_MASK: writers.get(fileno, noop).cb(fileno) if event & select.POLLNVAL: self.remove_descriptor(fileno) continue if event & EXC_MASK: readers.get(fileno, noop).cb(fileno) writers.get(fileno, noop).cb(fileno) except SYSTEM_EXCEPTIONS: raise except: self.squelch_exception(fileno, sys.exc_info()) clear_sys_exc_info() if self.debug_blocking: self.block_detect_post() seconds = 0
def switch(self): cur = greenlet.getcurrent() assert cur is not self.greenlet, "Cannot switch to MAINLOOP from MAINLOOP" switch_out = getattr(cur, "switch_out", None) if switch_out is not None: try: switch_out() except: self.squelch_generic_exception(sys.exc_info()) clear_sys_exc_info() if self.greenlet.dead: self.greenlet = greenlet.greenlet(self.run) try: if self.greenlet.parent is not cur: cur.parent = self.greenlet except ValueError: pass # gets raised if there is a greenlet parent cycle del cur, switch_out clear_sys_exc_info() return self.greenlet.switch()
def execute_polling(self): self.ditch_closed() try: events = self.poll.poll(0 if self.timer_fire_immediate() else -1) if not events or not self.fds: if events and not self.fds: # that should not ever happen, else it is unregister &? close filno print ('WARN', 'no fds map for', events) return True except ValueError: if not self.stopping: try: self.poll.close() except: pass self.poll = self.poll_backing self.poll_backing = select.epoll.fromfd(os.dup(self.poll.fileno())) return True return False except Exception as e: print (e, get_errno(e)) return True # use prior details, # a FD can be cancelled and a new created with the same filno which can't be on the current evs poll fds = self.fds for f, ev, details in [(f, ev, fds.get(f)) for f, ev in events if f in fds]: try: ev & READ_MASK and details.rs and details.rs[0]() ev & WRITE_MASK and details.ws and details.ws[0]() except SYSTEM_EXCEPTIONS: continue except: self.squelch_exception(f, sys.exc_info()) clear_sys_exc_info() continue ev & CLOSED_MASK and self._obsolete(f) return True
def wait(self, seconds=None): readers = self.listeners[READ] writers = self.listeners[WRITE] if not readers and not writers: if seconds: time.sleep(seconds) return while True: try: r, w, er = select.select(readers.keys(), writers.keys(), readers.keys() + writers.keys(), seconds) except select.error, e: if get_errno(e) == errno.EINTR: seconds = 0 continue elif get_errno(e) in BAD_SOCK: self._remove_bad_fds() seconds = 0 continue else: raise for fileno in er: readers.get(fileno, noop).cb(fileno) writers.get(fileno, noop).cb(fileno) if len(r) == 0 and len(w) == 0: return for listeners, events in ((readers, r), (writers, w)): for fileno in events: try: listeners.get(fileno, noop).cb(fileno) except self.SYSTEM_EXCEPTIONS: raise except: self.squelch_exception(fileno, sys.exc_info()) clear_sys_exc_info() seconds = 0
def wait(self, seconds=None): readers = self.listeners[self.READ] writers = self.listeners[self.WRITE] if not readers and not writers: if seconds: time.sleep(seconds) return result = self._control([], self.MAX_EVENTS, seconds) SYSTEM_EXCEPTIONS = self.SYSTEM_EXCEPTIONS for event in result: fileno = event.ident evfilt = event.filter try: if evfilt == select.KQ_FILTER_READ: readers.get(fileno, hub.noop).cb(fileno) if evfilt == select.KQ_FILTER_WRITE: writers.get(fileno, hub.noop).cb(fileno) except SYSTEM_EXCEPTIONS: raise except: self.squelch_exception(fileno, sys.exc_info()) support.clear_sys_exc_info()
def wait(self, seconds=None): readers = self.listeners[READ] writers = self.listeners[WRITE] if not readers and not writers: if seconds: time.sleep(seconds) return result = self._control([], self.MAX_EVENTS, seconds) SYSTEM_EXCEPTIONS = self.SYSTEM_EXCEPTIONS for event in result: fileno = event.ident evfilt = event.filter try: if evfilt == FILTERS[READ]: readers.get(fileno, noop).cb(fileno) if evfilt == FILTERS[WRITE]: writers.get(fileno, noop).cb(fileno) except SYSTEM_EXCEPTIONS: raise except: self.squelch_exception(fileno, sys.exc_info()) support.clear_sys_exc_info()
def wait(self, seconds=None): readers = self.listeners[READ] writers = self.listeners[WRITE] if not readers and not writers: if seconds: sleep(seconds) return result = self.kqueue.control([], self.MAX_EVENTS, seconds) SYSTEM_EXCEPTIONS = self.SYSTEM_EXCEPTIONS for event in result: fileno = event.ident evfilt = event.filter try: if evfilt == FILTERS[READ]: readers.get(fileno, noop).cb(fileno) if evfilt == FILTERS[WRITE]: writers.get(fileno, noop).cb(fileno) except SYSTEM_EXCEPTIONS: raise except: self.squelch_exception(fileno, sys.exc_info()) clear_sys_exc_info()
def done(): self.timer_canceled(timer) try: timer() except: clear_sys_exc_info()
def run(self, *a, **kw): """Run the runloop until abort is called. """ # accept and discard variable arguments because they will be # supplied if other greenlets have run and exited before the # hub's greenlet gets a chance to run if self.running: raise RuntimeError("Already running!") self.running = True self.stopping = False clock = self.clock timers = self.timers delay = 0 closed = self.closed pop_closed = self.closed.pop poll = self.poll.poll get_reader = self.listeners[READ].get get_writer = self.listeners[WRITE].get squelch_exception = self.squelch_exception while not self.stopping: if timers: exp, t = timers[0] # current evaluated timer if t.called: heappop(timers) # remove called/cancelled timer continue due = exp - clock() if due < 0: heappop(timers) # remove evaluated timer delay += due delay /= 2 try: t() except SYSTEM_EXCEPTIONS: raise except: pass due = 0 else: due += delay if due < 0: due = 0 else: due = DEFAULT_SLEEP while closed: # Ditch all closed fds first. l = pop_closed(-1) if not l.greenlet.dead: # There's no point signalling a greenlet that's already dead. l.tb(eventlet.hubs.IOClosed(errno.ENOTCONN, "Operation on closed file")) try: for f, ev in poll(due): try: if ev & EXC_MASK or ev & READ_MASK: l = get_reader(f) if l is not None: l.cb(f) if ev & EXC_MASK or ev & WRITE_MASK: l = get_writer(f) if l is not None: l.cb(f) if ev & POLLNVAL: self.remove_descriptor(f) except SYSTEM_EXCEPTIONS: raise except: squelch_exception(f, sys.exc_info()) clear_sys_exc_info() except (IOError, select.error) as e: if get_errno(e) == errno.EINTR: continue raise except SYSTEM_EXCEPTIONS: raise del self.timers[:] del self.closed[:] self.running = False self.stopping = False
def run(self, *a, **kw): """Run the runloop until abort is called. """ # accept and discard variable arguments because they will be # supplied if other greenlets have run and exited before the # hub's greenlet gets a chance to run if self.running: raise RuntimeError("Already running!") try: self.running = True self.stopping = False timers = self.timers next_timers = self.next_timers listeners = self.listeners listeners_events = self.listeners_events closed = self.closed close_one = self.close_one delay = 0 events_waiter = orig_threading.Thread(target=self.waiting_thread) events_waiter.start() self.event_notifier.set() event_notifier_wait = self.event_notifier.wait event_notifier_clear = self.event_notifier.clear while not self.stopping: debug_blocking = self.debug_blocking # Ditch all closed fds first. while closed: close_one(closed.pop(-1)) # Process all fds events while listeners_events: # call on fd cb evtype, fileno = listeners_events.popleft() if debug_blocking: self.block_detect_pre() try: if evtype is not None: l = listeners[evtype].get(fileno) if l is not None: l.cb(fileno) continue l = listeners[READ].get(fileno) if l is not None: l.cb(fileno) l = listeners[WRITE].get(fileno) if l is not None: l.cb(fileno) except SYSTEM_EXCEPTIONS: raise except: self.squelch_exception(fileno, sys.exc_info()) clear_sys_exc_info() if debug_blocking: self.block_detect_post() # Assign new timers while next_timers: timer = next_timers.pop(-1) if not timer.called: heappush(timers, (timer.scheduled_time, timer)) if not timers: if not listeners_events: # wait for fd signals event_notifier_wait(DEFAULT_SLEEP) event_notifier_clear() continue # current evaluated timer exp, timer = timers[0] if timer.called: # remove called/cancelled timer heappop(timers) continue sleep_time = exp - self.clock() if sleep_time > 0: sleep_time += delay if sleep_time <= 0: continue if not listeners_events and not next_timers: # wait for fd signals event_notifier_wait(sleep_time) event_notifier_clear() continue delay = (sleep_time+delay)/2 # delay is negative value # remove evaluated timer heappop(timers) # call on timer if debug_blocking: self.block_detect_pre() try: timer() except SYSTEM_EXCEPTIONS: raise except: if self.debug_exceptions: self.squelch_timer_exception(timer, sys.exc_info()) clear_sys_exc_info() if debug_blocking: self.block_detect_post() else: del self.timers[:] del self.next_timers[:] del self.listeners_events[:] finally: self.running = False self.stopping = False
class Hub(poll.Hub): def __init__(self, clock=time.time): BaseHub.__init__(self, clock) self.poll = zmq.Poller() def get_context(self, io_threads=1): """zmq's Context must be unique within a hub The zeromq API documentation states: All zmq sockets passed to the zmq_poll() function must share the same zmq context and must belong to the thread calling zmq_poll() As zmq_poll is what's eventually being called then we need to insure that all sockets that are going to be passed to zmq_poll (via hub.do_poll) are in the same context """ try: return _threadlocal.context except AttributeError: _threadlocal.context = zmq._Context(io_threads) return _threadlocal.context def register(self, fileno, new=False): mask = 0 if self.listeners[READ].get(fileno): mask |= READ_MASK if self.listeners[WRITE].get(fileno): mask |= WRITE_MASK if mask: self.poll.register(fileno, mask) else: self.poll.unregister(fileno) def wait(self, seconds=None): readers = self.listeners[READ] writers = self.listeners[WRITE] if not readers and not writers: if seconds: sleep(seconds) return try: presult = self.do_poll(seconds) except zmq.ZMQError, e: # In the poll hub this part exists to special case some exceptions # from socket. There may be some error numbers that wider use of # this hub will throw up as needing special treatment so leaving # this block and this comment as a remineder raise SYSTEM_EXCEPTIONS = self.SYSTEM_EXCEPTIONS if self.debug_blocking: self.block_detect_pre() for fileno, event in presult: try: if event & READ_MASK: readers.get(fileno, noop).cb(fileno) if event & WRITE_MASK: writers.get(fileno, noop).cb(fileno) if event & EXC_MASK: # zmq.POLLERR is returned for any error condition in the # underlying fd (as passed through to poll/epoll) readers.get(fileno, noop).cb(fileno) writers.get(fileno, noop).cb(fileno) except SYSTEM_EXCEPTIONS: raise except: self.squelch_exception(fileno, sys.exc_info()) clear_sys_exc_info() if self.debug_blocking: self.block_detect_post() # def do_poll(self, seconds): # print 'poll: ', seconds # if seconds < 0: # seconds = 500 # return self.poll.poll(seconds)
def run(self, *a, **kw): """Run the runloop until abort is called. """ # accept and discard variable arguments because they will be # supplied if other greenlets have run and exited before the # hub's greenlet gets a chance to run if self.running: raise RuntimeError("Already running!") try: self.running = True self.stopping = False timers = self.timers fire_timers = self.fire_timers prepare_timers = self.prepare_timers closed = self.closed pop_closed = self.closed.pop close_one = self.close_one wait = self.wait fd_events = self.listeners_events pop_fd_event = self.listeners_events.popleft listeners = self.listeners squelch_exception = self.squelch_exception sys_exec = self.SYSTEM_EXCEPTIONS while not self.stopping: # Ditch all closed fds first. while closed: close_one(pop_closed(-1)) prepare_timers() fire_timers(self.clock()) prepare_timers() if timers: sleep_time = timers[0][0] - self.clock() + self.timer_delay if sleep_time < 0: sleep_time = 0 else: sleep_time = self.default_sleep() wait(sleep_time) # Process all fds events while fd_events: ev, fileno = pop_fd_event() try: l = listeners[ev].get(fileno) if l: l.cb(fileno) except sys_exec: raise except: squelch_exception(fileno, sys.exc_info()) clear_sys_exc_info() else: del self.timers[:] del self.next_timers[:] del self.listeners_events[:] del self.closed[:] finally: self.running = False self.stopping = False
class Hub(BaseHub): def __init__(self, clock=time.time): super(Hub, self).__init__(clock) self.poll = select.poll() # poll.modify is new to 2.6 try: self.modify = self.poll.modify except AttributeError: self.modify = self.poll.register def add(self, evtype, fileno, cb): listener = super(Hub, self).add(evtype, fileno, cb) self.register(fileno, new=True) return listener def remove(self, listener): super(Hub, self).remove(listener) self.register(listener.fileno) def register(self, fileno, new=False): mask = 0 if self.listeners[READ].get(fileno): mask |= READ_MASK | EXC_MASK if self.listeners[WRITE].get(fileno): mask |= WRITE_MASK | EXC_MASK try: if mask: if new: self.poll.register(fileno, mask) else: try: self.modify(fileno, mask) except (IOError, OSError): self.poll.register(fileno, mask) else: try: self.poll.unregister(fileno) except (KeyError, IOError, OSError): # raised if we try to remove a fileno that was # already removed/invalid pass except ValueError: # fileno is bad, issue 74 self.remove_descriptor(fileno) raise def remove_descriptor(self, fileno): super(Hub, self).remove_descriptor(fileno) try: self.poll.unregister(fileno) except (KeyError, ValueError, IOError, OSError): # raised if we try to remove a fileno that was # already removed/invalid pass def do_poll(self, seconds): # poll.poll expects integral milliseconds return self.poll.poll(int(seconds * 1000.0)) def wait(self, seconds=None): readers = self.listeners[READ] writers = self.listeners[WRITE] if not readers and not writers: if seconds: sleep(seconds) return try: presult = self.do_poll(seconds) except (IOError, select.error), e: if get_errno(e) == errno.EINTR: return raise SYSTEM_EXCEPTIONS = self.SYSTEM_EXCEPTIONS if self.debug_blocking: self.block_detect_pre() for fileno, event in presult: try: if event & READ_MASK: readers.get(fileno, noop).cb(fileno) if event & WRITE_MASK: writers.get(fileno, noop).cb(fileno) if event & select.POLLNVAL: self.remove_descriptor(fileno) continue if event & EXC_MASK: readers.get(fileno, noop).cb(fileno) writers.get(fileno, noop).cb(fileno) except SYSTEM_EXCEPTIONS: raise except: self.squelch_exception(fileno, sys.exc_info()) clear_sys_exc_info() if self.debug_blocking: self.block_detect_post()
def squelch_timer_exception(self, timer, exc_info): if self.debug_exceptions: traceback.print_exception(*exc_info) sys.stderr.flush() clear_sys_exc_info()
def execute_polling(self): while self.closed: # Ditch all closed fds first. l = self.closed.pop(0) if not l.greenlet.dead: # There's no point signalling a greenlet that's already dead. l.tb( eventlet.hubs.IOClosed(errno.ENOTCONN, "Operation on closed file")) timers_immediate = self.timers_immediate if timers_immediate: immediate = timers_immediate[:] # copy current and exec without new to come del timers_immediate[:] for t in immediate: try: t() # exec immediate timer except: pass try: events = self.poll.poll(0 if timers_immediate else -1) except ValueError: if not self.stopping: try: self.poll.close() except: pass self.poll = self.poll_backing self.poll_backing = select.epoll.fromfd( os.dup(self.poll.fileno())) return True return False except Exception as e: print(e, get_errno(e)) return True # for f, ev in events: details = self.fds.get(f) if details: try: if ev & READ_MASK and details.rs: details.rs[0]() if ev & WRITE_MASK and details.ws: details.ws[0]() except SYSTEM_EXCEPTIONS: continue except: self.squelch_exception(f, sys.exc_info()) clear_sys_exc_info() continue if ev & CLOSED_MASK or ev & EPOLLRDHUP: self._obsolete(f) continue details = self.fd_timers.get(f) if details: try: self.timer_canceled(details) details() # exec timer except: pass continue details = self.fd_events.get(f) if details: try: details(int(eventfd_read(f))) except OSError as e: if get_errno(e) == errno.EBADF: details(-1) # recreate handler? # except io.BlockingIOError: -- write is not done with switch # pass # value is above/below int64 except: pass continue # return True
def run(self, *a, **kw): """Run the runloop until abort is called. """ # accept and discard variable arguments because they will be # supplied if other greenlets have run and exited before the # hub's greenlet gets a chance to run if self.running: raise RuntimeError("Already running!") self.running = True self.stopping = False if self.events_waiter is None or not self.events_waiter.is_alive(): self.events_waiter = orig_threading.Thread( target=self.waiting_thread) self.events_waiter.start() self.event_notifier.set() wait = self.event_notifier.wait wait_clear = self.event_notifier.clear timers = self.timers fire_timers = self.fire_timers prepare_timers = self.prepare_timers closed = self.closed pop_closed = self.closed.pop close_one = self.close_one fd_events = self.listeners_events pop_fd_event = fd_events.popleft listeners = self.listeners sys_exec = self.SYSTEM_EXCEPTIONS squelch_exception = self.squelch_exception try: while not self.stopping: # Ditch all closed fds first. while closed: close_one(pop_closed(-1)) prepare_timers() fire_timers(self.clock()) prepare_timers() if not fd_events: if timers: due = timers[0][0] - self.clock() + self.timer_delay if due < 0: continue else: due = self.default_sleep() wait(due) # wait for fd signals wait_clear() # Process all fds events while fd_events: ev, fileno = pop_fd_event() try: l = listeners[ev].get(fileno) if l: l.cb(fileno) except sys_exec: raise except: squelch_exception(fileno, sys.exc_info()) clear_sys_exc_info() else: del self.timers[:] del self.next_timers[:] del self.listeners_events[:] del self.closed[:] finally: self.running = False self.stopping = False
writers = self.listeners[WRITE] if not readers and not writers: if seconds: time.sleep(seconds) return try: r, w, er = select.select(readers.keys(), writers.keys(), readers.keys() + writers.keys(), seconds) except select.error, e: if get_errno(e) == errno.EINTR: return elif get_errno(e) in BAD_SOCK: self._remove_bad_fds() return else: raise for fileno in er: readers.get(fileno, noop).cb(fileno) writers.get(fileno, noop).cb(fileno) for listeners, events in ((readers, r), (writers, w)): for fileno in events: try: listeners.get(fileno, noop).cb(fileno) except self.SYSTEM_EXCEPTIONS: raise except: self.squelch_exception(fileno, sys.exc_info()) clear_sys_exc_info()
readers = self.listeners[READ] writers = self.listeners[WRITE] if not readers and not writers: if seconds: time.sleep(seconds) return try: r, w, er = select.select(readers.keys(), writers.keys(), readers.keys() + writers.keys(), seconds) except select.error, e: if get_errno(e) == errno.EINTR: return elif get_errno(e) in BAD_SOCK: self._remove_bad_fds() return else: raise for fileno in er: readers.get(fileno, noop).cb(fileno) writers.get(fileno, noop).cb(fileno) for listeners, events in ((readers, r), (writers, w)): for fileno in events: try: listeners.get(fileno, noop).cb(fileno) except self.SYSTEM_EXCEPTIONS: raise except: self.squelch_exception(fileno, sys.exc_info()) clear_sys_exc_info()
def squelch_generic_exception(self, exc_info): if self.debug_exceptions: traceback.print_exception(*exc_info) sys.stderr.flush() support.clear_sys_exc_info()
def run(self, *a, **kw): """Run the runloop until abort is called. """ # accept and discard variable arguments because they will be # supplied if other greenlets have run and exited before the # hub's greenlet gets a chance to run if self.running: raise RuntimeError("Already running!") self.running = True self.stopping = False if self.events_waiter is None or not self.events_waiter.is_alive(): self.events_waiter = orig_threading.Thread( target=self.waiting_thread) self.events_waiter.start() wait = self.event_has.wait wait_clear = self.event_has.clear want = self.event_want.set listeners = self.listeners timers = self.timers closed = self.closed pop_closed = self.closed.pop fd_events = self.listeners_events pop_fd_event = fd_events.popleft squelch_exception = self.squelch_exception clock = self.clock while not self.stopping: when = clock() while timers: exp, t = timers[0] # current evaluated timer if t.called: heappop(timers) # remove called/cancelled timer continue due = exp - when if due > 0: break heappop(timers) # remove evaluated timer try: t() except SYSTEM_EXCEPTIONS: raise except: pass continue else: due = DEFAULT_SLEEP if not fd_events: wait(due) # wait for fd signals wait_clear() while fd_events: fileno, ev = fd_events[0] try: l = listeners[ev].get(fileno) if l: l.cb(fileno) except SYSTEM_EXCEPTIONS: raise except: squelch_exception(fileno, sys.exc_info()) clear_sys_exc_info() pop_fd_event() want() while closed: # Ditch all closed fds first. l = pop_closed(-1) if not l.greenlet.dead: # There's no point signalling a greenlet that's already dead. l.tb( eventlet.hubs.IOClosed(errno.ENOTCONN, "Operation on closed file")) del self.timers[:] del self.listeners_events[:] self.running = False self.stopping = False