def __init__(self, impl=None): self._impl = impl or _poll() if hasattr(self._impl, 'fileno'): self._set_close_exec(self._impl.fileno()) self._handlers = {} self._events = {} self._callbacks = set() self._timeouts = [] self._running = False self._stopped = False self._blocking_log_threshold = None # Create a pipe that we send bogus data to when we want to wake # the I/O loop when it is idle if os.name != 'nt': r, w = os.pipe() self._set_nonblocking(r) self._set_nonblocking(w) self._set_close_exec(r) self._set_close_exec(w) self._waker_reader = os.fdopen(r, "r", 0) self._waker_writer = os.fdopen(w, "w", 0) else: self._waker_reader = self._waker_writer = win32_support.Pipe() r = self._waker_writer.reader_fd self.add_handler(r, self._read_waker, self.READ)
def __init__(self, impl=None): self._impl = impl or _poll() self._handlers = {} self._callbacks = set() self._events = {} # 目前只是一个 list pop # 新版本将是一个最小堆结构,按照超时时间从小到大排列的 fd 的任务堆( 通常这个任务都会包含一个 callback ) self._timeouts = [] self._running = False self._stopped = False self._blocking_log_threshold = None # create a pipe that we send bogus data to when we want to wake # the I?O loop when it is idle if os.name != 'nt': r, w = os.pipe() self._set_nonblocking(r) self._set_nonblocking(w) self._set_close_exec(r) self._set_close_exec(w) self._waker_reader = os.fdopen(r, "r", 0) self._waker_writer = os.fdopen(w, "w", 0) print "===", os.name else: self._waker_reader = self._waker_writer = win32_support.Pipe() r = self._waker_writer.reader_fd print "passsssssss ", os.name self.add_handler(r, self._read_waker, self.READ)
def __init__(self, impl=None): self._impl = impl or _poll() if hasattr(self._impl, 'fileno'): self._set_close_exec(self._impl.fileno()) self._handlers = {} self._events = {} self._callbacks = set() self._timeouts = [] self._running = False self._stopped = False self._blocking_log_threshold = None if os.name != 'nt': r, w = os.pipe() self._set_nonblocking(r) self._set_nonblocking(w) self._set_close_exec(r) self._set_close_exec(w) self._waker_reader = os.fdopen(r, "r", 0) self._waker_writer = os.fdopen(w, "w", 0) else: self._waker_reader = self._waker_writer = win32_support.Pipe() r = self._waker_writer.reader_fd self.add_handler(r, self._read_waker, self.READ) @classmethod def instance(cls): if not hasattr(cls, "_instance"): cls._instance = cls() return cls._instance @classmethod def initialized(cls): return hasattr(cls, "_instance") def add_handler(self, fd, handler, events): self._handlers[fd] = handler self._impl.register(fd, events | self.ERROR) def update_handler(self, fd, events): self._impl.modify(fd, events | self.ERROR) def remove_handler(self, fd): self._handlers.pop(fd, None) self._events.pop(fd, None) try: self._impl.unregister(fd) except (OSError, IOError): logging.debug("error remove_handler", exc_info=True) def set_blocking_log_threshold(self, s): if not hasattr(signal, "setitimer"): logging.error("error set_blocking_log_threshold") return def start(self): if self._stopped: self._stopped = False return self._running = True while True: poll_timeout = 0.2 callbacks = list(self._callbacks) for callback in callbacks: if callback in self._callbacks: self._callbacks.remove(callback) self._run_callback(callback) if self._callbacks: poll_timeout = 0.0 if self._timeouts: now = time.time() while self._timeouts and self._timeouts[0].deadline <= now timeout = self.timeouts.pop(0) poll_timeout = min(milliseconds, poll_timeout) if not self._running: break if self._blocking_log_threshold is not None: signal.setitimer(signal.ITIMER_REAL, 0, 0) try: event_pairs = self._impl.poll(poll_timeout) except Exception, e: if (getattr(e, 'errno') == errno.EINTR or (isinstance(getattr(e, 'args'), tuple) and len(e.args) == 2 and e.args[0] == errno.EINTR)): logging.warning("warning system call", exc_info=1) continue else: raise if self._blocking_log_threshold is not None: signal.setitimer(signal.ITIMER_REAL, self.blocking_log_threshold, 0) self._events.update(event_pairs) while self._events: fd, events = self._events.popitem() try: self._handlers[fd](fd, events) except (KeyboardInterrupt, SystemExit): raise except (OSError, IOError), e: if e[0] == errno.EPIPE: pass else: logging.error("error I/O handler") except: logging.error("error I/O handler")