def sock_send(self, sock, data): try: s = sock.send(data) data = data[s:] except (OSError, IOError) as e: if errno_from_exception(e) in (errno.EAGAIN, errno.EWOULDBLOCK, errno.EINPROGRESS, errno.EINTR): pass else: raise return data
def sock_recv(self, sock, size=BUF_SIZE): try: data = sock.recv(size) if not data: self.close() except (OSError, IOError) as e: if errno_from_exception(e) in (errno.EAGAIN, errno.EWOULDBLOCK, errno.EINTR): return else: raise return data
def sock_connect(self, sock, addr): while True: try: sock.connect(addr) except (OSError, IOError) as e: err = errno_from_exception(e) if err == errno.EINTR: pass elif err == errno.EINPROGRESS: break else: raise else: break
def _accept(self, listen_sock): try: sock, addr = listen_sock.accept() except (OSError, IOError) as e: if errno_from_exception(e) in (errno.EAGAIN, errno.EWOULDBLOCK, errno.EINPROGRESS, errno.EINTR, errno.ECONNABORTED): pass else: raise logging.info('Connected from {}:{}'.format(*addr)) sock.setblocking(False) sock.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, 1) return (sock, addr)
def run(self): logging.debug('Starting event loop') while not self._stopping: asap = False try: events = self.poll(timeout=TIMEOUT_PRECISION) except (OSError, IOError) as e: if errno_from_exception(e) in (errno.EPIPE, errno.EINTR): # EPIPE: Happens when the client closes the connection # EINTR: Happens when received a signal # handles them as soon as possible asap = True logging.debug('poll: %s', e) else: logging.error('poll: %s', e) traceback.print_exc() continue for key, event in events: if type(key.data) == tuple: handler = key.data[0] args = key.data[1:] else: handler = key.data args = () sock = key.fileobj if hasattr(handler, 'handle_event'): handler = handler.handle_event try: handler(sock, event, *args) except Exception as e: logging.debug(e) traceback.print_exc() raise now = time.time() if asap or now - self._last_time >= TIMEOUT_PRECISION: for callback in self._periodic_callbacks: callback() self._last_time = now logging.debug('Got {} fds registered'.format(self.fd_count())) logging.debug('Stopping event loop') self._selector.close()