def runloop(self, timeout): """ Run epoll main loop. """ if not timeout: timeout = -1 start_time = time.time() # run main event loop... while self.evlooprefcnt > 0: self._debug("LOOP evlooprefcnt=%d (reg_clifds=%s) (timers=%d)" % \ (self.evlooprefcnt, self.reg_clifds.keys(), len(self.timerq))) try: timeo = self.timerq.nextfire_delay() if timeout > 0 and timeo >= timeout: # task timeout may invalidate clients timeout self.timerq.clear() timeo = timeout elif timeo == -1: timeo = timeout self._current_loopcnt += 1 evlist = self.epolling.poll(timeo + 0.001) except IOError, ex: # might get interrupted by a signal if ex.errno == errno.EINTR: continue for fd, event in evlist: # get client instance client, stream = self._fd2client(fd) if client is None: continue fdev = stream.evmask fname = stream.name # set as current processed client self._current_client = client # check for poll error condition of some sort if event & select.EPOLLERR: self._debug("EPOLLERR fd=%d fname=%s fdev=0x%x (%s)" % \ (fd, fname, fdev, client)) assert fdev & E_WRITE self.remove_stream(client, stream) self._current_client = None continue # check for data to read if event & select.EPOLLIN: assert fdev & E_READ assert stream.events & fdev, (stream.events, fdev) self.modify(client, fname, 0, fdev) try: client._handle_read(fname) except EngineClientEOF: self._debug("EngineClientEOF %s %s" % (client, fname)) self.remove_stream(client, stream) self._current_client = None continue # or check for end of stream (do not handle both at the same # time because handle_read() may perform a partial read) elif event & select.EPOLLHUP: assert fdev & E_READ, "fdev 0x%x & E_READ" % fdev self._debug("EPOLLHUP fd=%d fname=%s %s (%s)" % \ (fd, fname, client, client.streams)) self.remove_stream(client, stream) self._current_client = None continue # check for writing if event & select.EPOLLOUT: self._debug("EPOLLOUT fd=%d fname=%s %s (%s)" % \ (fd, fname, client, client.streams)) assert fdev & E_WRITE assert stream.events & fdev, (stream.events, fdev) self.modify(client, fname, 0, fdev) client._handle_write(fname) self._current_client = None # apply any changes occured during processing if client.registered: self.set_events(client, stream) # check for task runloop timeout if timeout > 0 and time.time() >= start_time + timeout: raise EngineTimeoutException() # process clients timeout self.fire_timers()
def runloop(self, timeout): """ Select engine run(): start clients and properly get replies """ if not timeout: timeout = -1 start_time = time.time() # run main event loop... while self.evlooprefcnt > 0: self._debug( "LOOP evlooprefcnt=%d (reg_clifds=%s) (timers=%d)" % (self.evlooprefcnt, self.reg_clifds.keys(), len(self.timerq))) try: timeo = self.timerq.nextfire_delay() if timeout > 0 and timeo >= timeout: # task timeout may invalidate clients timeout self.timerq.clear() timeo = timeout elif timeo == -1: timeo = timeout self._current_loopcnt += 1 if timeo >= 0: r_ready, w_ready, x_ready = \ select.select(self._fds_r, self._fds_w, [], timeo) else: # no timeout specified, do not supply the timeout argument r_ready, w_ready, x_ready = \ select.select(self._fds_r, self._fds_w, []) except select.error, (ex_errno, ex_strerror): # might get interrupted by a signal if ex_errno == errno.EINTR: continue elif ex_errno in [errno.EINVAL, errno.EBADF, errno.ENOMEM]: msg = "Increase RLIMIT_NOFILE?" logging.getLogger(__name__).error(msg) raise # iterate over fd on which events occured for fd in set(r_ready) | set(w_ready): # get client instance client, stream = self._fd2client(fd) if client is None: continue fdev = stream.evmask sname = stream.name # process this stream self._current_stream = stream # check for possible unblocking read on this fd if fd in r_ready: self._debug( "R_READY fd=%d %s (%s)" % (fd, client.__class__.__name__, client.streams)) assert fdev & E_READ assert stream.events & fdev self.modify(client, sname, 0, fdev) try: client._handle_read(sname) except EngineClientEOF: self._debug("EngineClientEOF %s" % client) self.remove_stream(client, stream) # check for writing if fd in w_ready: self._debug( "W_READY fd=%d %s (%s)" % (fd, client.__class__.__name__, client.streams)) assert fdev == E_WRITE assert stream.events & fdev self.modify(client, sname, 0, fdev) client._handle_write(sname) # post processing self._current_stream = None # apply any changes occured during processing if client.registered: self.set_events(client, stream) # check for task runloop timeout if timeout > 0 and time.time() >= start_time + timeout: raise EngineTimeoutException() # process clients timeout self.fire_timers()
def runloop(self, timeout): """ Select engine run(): start clients and properly get replies """ if timeout == 0: timeout = -1 start_time = time.time() # run main event loop... while self.evlooprefcnt > 0: self._debug( "LOOP evlooprefcnt=%d (reg_clifds=%s) (timers=%d)" % (self.evlooprefcnt, self.reg_clifds.keys(), len(self.timerq))) try: timeo = self.timerq.nextfire_delay() if timeout > 0 and timeo >= timeout: # task timeout may invalidate clients timeout self.timerq.clear() timeo = timeout elif timeo == -1: timeo = timeout self._current_loopcnt += 1 if timeo >= 0: r_ready, w_ready, x_ready = \ select.select(self._fds_r, self._fds_w, [], timeo) else: # no timeout specified, do not supply the timeout argument r_ready, w_ready, x_ready = \ select.select(self._fds_r, self._fds_w, []) except select.error, (ex_errno, ex_strerror): # might get interrupted by a signal if ex_errno == errno.EINTR: continue elif ex_errno in [errno.EINVAL, errno.EBADF, errno.ENOMEM]: print >> sys.stderr, "EngineSelect: %s" % ex_strerror else: raise # iterate over fd on which events occured for fd in set(r_ready) | set(w_ready): # get client instance client, fdev = self._fd2client(fd) if client is None: continue # process this client client._current_client = client # check for possible unblocking read on this fd if fd in r_ready: assert fdev & (Engine.E_READ | Engine.E_ERROR) assert client._events & fdev self.modify(client, 0, fdev) try: if fdev & Engine.E_READ: client._handle_read() else: client._handle_error() except EngineClientEOF: self._debug("EngineClientEOF %s" % client) # if the EOF occurs on E_READ... if fdev & Engine.E_READ: # and if the client is also waiting for E_ERROR if client._events & Engine.E_ERROR: # just clear the event for E_READ self.modify(client, 0, fdev) else: # otherwise we can remove the client self.remove(client) else: # same thing in the other order... if client._events & Engine.E_READ: self.modify(client, 0, fdev) else: self.remove(client) # check for writing if fd in w_ready: self._debug( "W_READY fd=%d %s (r%s,e%s,w%s)" % (fd, client.__class__.__name__, client.reader_fileno(), client.error_fileno(), client.writer_fileno())) assert fdev == Engine.E_WRITE assert client._events & fdev self.modify(client, 0, fdev) client._handle_write() # post processing self._current_client = None # apply any changes occured during processing if client.registered: self.set_events(client, client._new_events) # check for task runloop timeout if timeout > 0 and time.time() >= start_time + timeout: raise EngineTimeoutException() # process clients timeout self.fire_timers()
def runloop(self, timeout): """ Poll engine run(): start clients and properly get replies """ if not timeout: timeout = -1 start_time = time.time() # run main event loop... while self.evlooprefcnt > 0: self._debug("LOOP evlooprefcnt=%d (reg_clifds=%s) (timers=%d)" \ % (self.evlooprefcnt, self.reg_clifds.keys(), \ len(self.timerq))) try: timeo = self.timerq.nextfire_delay() if timeout > 0 and timeo >= timeout: # task timeout may invalidate clients timeout self.timerq.clear() timeo = timeout elif timeo == -1: timeo = timeout self._current_loopcnt += 1 evlist = self.polling.poll(timeo * 1000.0 + 1.0) except select.error, (ex_errno, ex_strerror): # might get interrupted by a signal if ex_errno == errno.EINTR: continue elif ex_errno == errno.EINVAL: print >> sys.stderr, \ "EnginePoll: please increase RLIMIT_NOFILE" raise for fd, event in evlist: if event & select.POLLNVAL: raise EngineException("Caught POLLNVAL on fd %d" % fd) # get client instance client, stream = self._fd2client(fd) if client is None: continue fdev = stream.evmask sname = stream.name # process this stream self._current_stream = stream # check for poll error condition of some sort if event & select.POLLERR: self._debug("POLLERR %s" % client) assert fdev & E_WRITE self._debug("POLLERR: remove_stream sname %s fdev 0x%x" % (sname, fdev)) self.remove_stream(client, stream) self._current_stream = None continue # check for data to read if event & select.POLLIN: assert fdev & E_READ assert stream.events & fdev, (stream.events, fdev) self.modify(client, sname, 0, fdev) try: client._handle_read(sname) except EngineClientEOF: self._debug("EngineClientEOF %s %s" % (client, sname)) self.remove_stream(client, stream) self._current_stream = None continue # or check for end of stream (do not handle both at the same # time because handle_read() may perform a partial read) elif event & select.POLLHUP: self._debug( "POLLHUP fd=%d %s (%s)" % (fd, client.__class__.__name__, client.streams)) self.remove_stream(client, stream) self._current_stream = None continue # check for writing if event & select.POLLOUT: self._debug( "POLLOUT fd=%d %s (%s)" % (fd, client.__class__.__name__, client.streams)) assert fdev == E_WRITE assert stream.events & fdev self.modify(client, sname, 0, fdev) client._handle_write(sname) self._current_stream = None # apply any changes occured during processing if client.registered: self.set_events(client, stream) # check for task runloop timeout if timeout > 0 and time.time() >= start_time + timeout: raise EngineTimeoutException() # process clients timeout self.fire_timers()
def runloop(self, timeout): """ Run epoll main loop. """ if timeout == 0: timeout = -1 start_time = time.time() # run main event loop... while self.evlooprefcnt > 0: self._debug("LOOP evlooprefcnt=%d (reg_clifds=%s) (timers=%d)" % \ (self.evlooprefcnt, self.reg_clifds.keys(), len(self.timerq))) try: timeo = self.timerq.nextfire_delay() if timeout > 0 and timeo >= timeout: # task timeout may invalidate clients timeout self.timerq.clear() timeo = timeout elif timeo == -1: timeo = timeout self._current_loopcnt += 1 evlist = self.epolling.poll(timeo + 0.001) except IOError, ex: # might get interrupted by a signal if ex.errno == errno.EINTR: continue for fd, event in evlist: # get client instance client, fdev = self._fd2client(fd) if client is None: continue # set as current processed client self._current_client = client # check for poll error condition of some sort if event & select.EPOLLERR: self._debug("EPOLLERR %s" % client) client._close_writer() self._current_client = None continue # check for data to read if event & select.EPOLLIN: #self._debug("EPOLLIN fd=%d %s" % (fd, client)) assert fdev & (Engine.E_READ | Engine.E_ERROR) assert client._events & fdev self.modify(client, 0, fdev) try: if fdev & Engine.E_READ: client._handle_read() else: client._handle_error() except EngineClientEOF: self._debug("EngineClientEOF %s" % client) if fdev & Engine.E_READ: self.remove(client) self._current_client = None continue # or check for end of stream (do not handle both at the same # time because handle_read() may perform a partial read) elif event & select.EPOLLHUP: self._debug( "EPOLLHUP fd=%d %s (r%s,e%s,w%s)" % (fd, client.__class__.__name__, client.fd_reader, client.fd_error, client.fd_writer)) if fdev & Engine.E_READ: if client._events & Engine.E_ERROR: self.modify(client, 0, fdev) else: self.remove(client) else: if client._events & Engine.E_READ: self.modify(client, 0, fdev) else: self.remove(client) # check for writing if event & select.EPOLLOUT: self._debug( "EPOLLOUT fd=%d %s (r%s,e%s,w%s)" % (fd, client.__class__.__name__, client.fd_reader, client.fd_error, client.fd_writer)) assert fdev == Engine.E_WRITE assert client._events & fdev self.modify(client, 0, fdev) client._handle_write() self._current_client = None # apply any changes occured during processing if client.registered: self.set_events(client, client._new_events) # check for task runloop timeout if timeout > 0 and time.time() >= start_time + timeout: raise EngineTimeoutException() # process clients timeout self.fire_timers()