Select for reads or writes with a timeout in seconds (or None). Returns True if the socket is readable/writable, False on timeout.
(
self, sock: Any, read: bool = False, write: bool = False, timeout: Optional[float] = 0
)
| 40 | self._poller = None |
| 41 | |
| 42 | def select( |
| 43 | self, sock: Any, read: bool = False, write: bool = False, timeout: Optional[float] = 0 |
| 44 | ) -> bool: |
| 45 | """Select for reads or writes with a timeout in seconds (or None). |
| 46 | |
| 47 | Returns True if the socket is readable/writable, False on timeout. |
| 48 | """ |
| 49 | res: Any |
| 50 | while True: |
| 51 | try: |
| 52 | if self._poller: |
| 53 | mask = select.POLLERR | select.POLLHUP |
| 54 | if read: |
| 55 | mask = mask | select.POLLIN | select.POLLPRI |
| 56 | if write: |
| 57 | mask = mask | select.POLLOUT |
| 58 | self._poller.register(sock, mask) |
| 59 | try: |
| 60 | # poll() timeout is in milliseconds. select() |
| 61 | # timeout is in seconds. |
| 62 | timeout_ = None if timeout is None else timeout * 1000 |
| 63 | res = self._poller.poll(timeout_) |
| 64 | # poll returns a possibly-empty list containing |
| 65 | # (fd, event) 2-tuples for the descriptors that have |
| 66 | # events or errors to report. Return True if the list |
| 67 | # is not empty. |
| 68 | return bool(res) |
| 69 | finally: |
| 70 | self._poller.unregister(sock) |
| 71 | else: |
| 72 | rlist = [sock] if read else [] |
| 73 | wlist = [sock] if write else [] |
| 74 | res = select.select(rlist, wlist, [sock], timeout) |
| 75 | # select returns a 3-tuple of lists of objects that are |
| 76 | # ready: subsets of the first three arguments. Return |
| 77 | # True if any of the lists are not empty. |
| 78 | return any(res) |
| 79 | except (_SelectError, OSError) as exc: # type: ignore |
| 80 | if _errno_from_exception(exc) in (errno.EINTR, errno.EAGAIN): |
| 81 | continue |
| 82 | raise |
| 83 | |
| 84 | def socket_closed(self, sock: Any) -> bool: |
| 85 | """Return True if we know socket has been closed, False otherwise.""" |