def initialize(self): self._impl=select.epoll() self._running = False self._handlers = {} self._events = {} self._callbacks = [] self._callback_lock = threading.Lock() # Create a pipe that we send bogus data to when we want to wake # the I/O loop when it is idle self._waker = Waker() self.add_handler(self._waker.fileno(), lambda fd, events: self._waker.consume(), #args:fd,events self.READ) #_EPOLLIN
class PollIOLoop(IOLoop): def initialize(self): self._impl=select.epoll() self._running = False self._handlers = {} self._events = {} self._callbacks = [] self._callback_lock = threading.Lock() # Create a pipe that we send bogus data to when we want to wake # the I/O loop when it is idle self._waker = Waker() self.add_handler(self._waker.fileno(), lambda fd, events: self._waker.consume(), #args:fd,events self.READ) #_EPOLLIN def add_handler(self, fd, handler, events): """Registers the given handler to receive the given events for ``fd``. """ self._handlers[fd] = handler self._impl.register(fd, events|self.ERROR) def remove_handler(self, fd): self._handlers.pop(fd, None) self._events.pop(fd, None) def add_callback(self, callback, *args, **kwargs): """Calls the given callback on the next I/O loop iteration. """ with self._callback_lock: if self._closing: raise RuntimeError("IOLoop is closing") self._callbacks.append(functools.partial(callback,*args, **kwargs)) self._waker.wake() def start(self): if self._running: raise RuntimeError("IOLoop is already running") self._running = True while True: #work loop with self._callback_lock: callbacks = self._callbacks self._callbacks = [] for callback in callbacks: self._run_callback(callback) # Closures may be holding on to a lot of memory, so allow # them to be freed before we go into our poll wait. callbacks = callback = None if self._callbacks: # If any callbacks or timeouts called add_callback, # we don't want to wait in poll() before we run them. poll_timeout = 0.0 else: poll_timeout = _POLL_TIMEOUT if not self._running: # stop() is called during the loop break event_pairs = self._impl.poll(poll_timeout) # there may be reentrant calls to events self._events.update(event_pairs) while self._events: fd, events = self._events.popitem() fd_obj, handler_func = self._handlers[fd] handler_func(fd_obj, events) def stop(self): self._running = False self._stopped = True self._waker.wake() def close(): with self._callback_lock: self._closing = True self.remove_handler(self._waker.fileno())