def _loop(self, handler): """Serve handler's IO loop in a separate thread or process.""" ioloop = IOLoop() try: handler.ioloop = ioloop try: handler.add_channel() except EnvironmentError: err = sys.exc_info()[1] if err.errno == errno.EBADF: # we might get here in case the other end quickly # disconnected (see test_quick_connect()) return else: raise # Here we localize variable access to minimize overhead. poll = ioloop.poll socket_map = ioloop.socket_map tasks = ioloop.sched._tasks sched_poll = ioloop.sched.poll poll_timeout = getattr(self, 'poll_timeout', None) soonest_timeout = poll_timeout while socket_map and not self._exit.is_set(): try: poll(timeout=soonest_timeout) if tasks: soonest_timeout = sched_poll() else: soonest_timeout = None except (KeyboardInterrupt, SystemExit): # note: these two exceptions are raised in all sub # processes self._exit.set() except select.error: # on Windows we can get WSAENOTSOCK if the client # rapidly connect and disconnects err = sys.exc_info()[1] if os.name == 'nt' and err.args[0] == 10038: for fd in socket_map.keys(): try: select.select([fd], [], [], 0) except select.error: logger.info("discarding broken socket %r", socket_map[fd]) del socket_map[fd] else: raise else: if poll_timeout: if soonest_timeout is None \ or soonest_timeout > poll_timeout: soonest_timeout = poll_timeout finally: try: self._active_tasks.remove(self._current_task()) except ValueError: pass ioloop.close()
class TestFTPServer(TestServer): def __init__(self, username, password, address, port, use_ssl, top_dir): self.ioloop = IOLoop() self.thread = threading.Thread(target=run_ftp_server, args=[ username, password, address, port, use_ssl, top_dir, self.ioloop ]) def stop(self): self.ioloop.close() self.thread.join()
def _loop(self, handler): """Serve handler's IO loop in a separate thread or process.""" ioloop = IOLoop() try: handler.ioloop = ioloop try: handler.add_channel() except EnvironmentError: err = sys.exc_info()[1] if err.errno == errno.EBADF: # we might get here in case the other end quickly # disconnected (see test_quick_connect()) return else: raise # Here we localize variable access to minimize overhead. poll = ioloop.poll sched_poll = ioloop.sched.poll poll_timeout = getattr(self, 'poll_timeout', None) soonest_timeout = poll_timeout while (ioloop.socket_map or ioloop.sched._tasks) and \ not self._exit.is_set(): try: if ioloop.socket_map: poll(timeout=soonest_timeout) if ioloop.sched._tasks: soonest_timeout = sched_poll() # Handle the case where socket_map is emty but some # cancelled scheduled calls are still around causing # this while loop to hog CPU resources. # In theory this should never happen as all the sched # functions are supposed to be cancel()ed on close() # but by using threads we can incur into # synchronization issues such as this one. # https://github.com/giampaolo/pyftpdlib/issues/245 if not ioloop.socket_map: # get rid of cancel()led calls ioloop.sched.reheapify() soonest_timeout = sched_poll() if soonest_timeout: time.sleep(min(soonest_timeout, 1)) else: soonest_timeout = None except (KeyboardInterrupt, SystemExit): # note: these two exceptions are raised in all sub # processes self._exit.set() except select.error: # on Windows we can get WSAENOTSOCK if the client # rapidly connect and disconnects err = sys.exc_info()[1] if os.name == 'nt' and err.args[0] == 10038: for fd in list(ioloop.socket_map.keys()): try: select.select([fd], [], [], 0) except select.error: try: logger.info("discarding broken socket %r", ioloop.socket_map[fd]) del ioloop.socket_map[fd] except KeyError: # dict changed during iteration pass else: raise else: if poll_timeout: if (soonest_timeout is None or soonest_timeout > poll_timeout): soonest_timeout = poll_timeout finally: ioloop.close()
def _loop(self, handler): """Serve handler's IO loop in a separate thread or process.""" ioloop = IOLoop() try: handler.ioloop = ioloop try: handler.add_channel() except EnvironmentError: err = sys.exc_info()[1] if err.errno == errno.EBADF: # we might get here in case the other end quickly # disconnected (see test_quick_connect()) return else: raise # Here we localize variable access to minimize overhead. poll = ioloop.poll socket_map = ioloop.socket_map tasks = ioloop.sched._tasks sched_poll = ioloop.sched.poll poll_timeout = getattr(self, 'poll_timeout', None) soonest_timeout = poll_timeout while (socket_map or tasks) and not self._exit.is_set(): try: if socket_map: poll(timeout=soonest_timeout) if tasks: soonest_timeout = sched_poll() else: soonest_timeout = None except (KeyboardInterrupt, SystemExit): # note: these two exceptions are raised in all sub # processes self._exit.set() except select.error: # on Windows we can get WSAENOTSOCK if the client # rapidly connect and disconnects err = sys.exc_info()[1] if os.name == 'nt' and err.args[0] == 10038: for fd in list(socket_map.keys()): try: select.select([fd], [], [], 0) except select.error: try: logger.info("discarding broken socket %r", socket_map[fd]) del socket_map[fd] except KeyError: # dict changed during iteration pass else: raise else: if poll_timeout: if soonest_timeout is None \ or soonest_timeout > poll_timeout: soonest_timeout = poll_timeout finally: try: self._active_tasks.remove(self._current_task()) except ValueError: pass ioloop.close()