def select(rlist, wlist, xlist, timeout=None): # pylint:disable=unused-argument """An implementation of :meth:`select.select` that blocks only the current greenlet. .. caution:: *xlist* is ignored. .. versionchanged:: 1.2a1 Raise a :exc:`ValueError` if timeout is negative. This matches Python 3's behaviour (Python 2 would raise a ``select.error``). Previously gevent had undefined behaviour. .. versionchanged:: 1.2a1 Raise an exception if any of the file descriptors are invalid. """ if timeout is not None and timeout < 0: # Raise an error like the real implementation; which error # depends on the version. Python 3, where select.error is OSError, # raises a ValueError (which makes sense). Older pythons raise # the error from the select syscall...but we don't actually get there. # We choose to just raise the ValueError as it makes more sense and is # forward compatible raise ValueError("timeout must be non-negative") # First, do a poll with the original select system call. This is # the most efficient way to check to see if any of the file # descriptors have previously been closed and raise the correct # corresponding exception. (Because libev tends to just return # them as ready, or, if built with EV_VERIFY >= 2 and libev >= # 4.27, crash the process. And libuv also tends to crash the # process.) # # We accept the *xlist* here even though we can't # below because this is all about error handling. sel_results = ((), (), ()) try: sel_results = _original_select(rlist, wlist, xlist, 0) except error as e: enumber = getattr(e, 'errno', None) or e.args[0] if enumber != EINTR: # Ignore interrupted syscalls raise if sel_results[0] or sel_results[1] or sel_results[2] or ( timeout is not None and timeout == 0): # If we actually had stuff ready, go ahead and return it. No need # to go through the trouble of doing our own stuff. # Likewise, if the timeout is 0, we already did a 0 timeout # select and we don't need to do it again. Note that in libuv, # zero duration timers may be called immediately, without # cycling the event loop at all. 2.7/test_telnetlib.py "hangs" # calling zero-duration timers if we go to the loop here. # However, because this is typically a place where scheduling switches # can occur, we need to make sure that's still the case; otherwise a single # consumer could monopolize the thread. (shows up in test_ftplib.) _g_sleep() return sel_results result = SelectResult() return result.select(rlist, wlist, timeout)
def select(rlist, wlist, xlist, timeout=None): # pylint:disable=unused-argument """An implementation of :meth:`select.select` that blocks only the current greenlet. .. caution:: *xlist* is ignored. .. versionchanged:: 1.2a1 Raise a :exc:`ValueError` if timeout is negative. This matches Python 3's behaviour (Python 2 would raise a ``select.error``). Previously gevent had undefined behaviour. .. versionchanged:: 1.2a1 Raise an exception if any of the file descriptors are invalid. """ if timeout is not None and timeout < 0: # Raise an error like the real implementation; which error # depends on the version. Python 3, where select.error is OSError, # raises a ValueError (which makes sense). Older pythons raise # the error from the select syscall...but we don't actually get there. # We choose to just raise the ValueError as it makes more sense and is # forward compatible raise ValueError("timeout must be non-negative") # First, do a poll with the original select system call. This # is the most efficient way to check to see if any of the file descriptors # have previously been closed and raise the correct corresponding exception. # (Because libev tends to just return them as ready...) # We accept the *xlist* here even though we can't below because this is all about # error handling. sel_results = ((), (), ()) try: sel_results = _original_select(rlist, wlist, xlist, 0) except error as e: enumber = getattr(e, 'errno', None) or e.args[0] if enumber != EINTR: # Ignore interrupted syscalls raise if sel_results[0] or sel_results[1] or sel_results[2] or (timeout is not None and timeout == 0): # If we actually had stuff ready, go ahead and return it. No need # to go through the trouble of doing our own stuff. # Likewise, if the timeout is 0, we already did a 0 timeout # select and we don't need to do it again. Note that in libuv, # zero duration timers may be called immediately, without # cycling the event loop at all. 2.7/test_telnetlib.py "hangs" # calling zero-duration timers if we go to the loop here. # However, because this is typically a place where scheduling switches # can occur, we need to make sure that's still the case; otherwise a single # consumer could monopolize the thread. (shows up in test_ftplib.) _g_sleep() return sel_results result = SelectResult() return result.select(rlist, wlist, timeout)