Block until at least one byte is read, or a timeout, or a cancel.
(conn: Connection, deadline: Optional[float])
| 290 | |
| 291 | |
| 292 | def wait_for_read(conn: Connection, deadline: Optional[float]) -> None: |
| 293 | """Block until at least one byte is read, or a timeout, or a cancel.""" |
| 294 | sock = conn.conn.sock |
| 295 | timed_out = False |
| 296 | # Check if the connection's socket has been manually closed |
| 297 | if sock.fileno() == -1: |
| 298 | return |
| 299 | while True: |
| 300 | # SSLSocket can have buffered data which won't be caught by select. |
| 301 | if hasattr(sock, "pending") and sock.pending() > 0: |
| 302 | readable = True |
| 303 | else: |
| 304 | # Wait up to 500ms for the socket to become readable and then |
| 305 | # check for cancellation. |
| 306 | if deadline: |
| 307 | remaining = deadline - time.monotonic() |
| 308 | # When the timeout has expired perform one final check to |
| 309 | # see if the socket is readable. This helps avoid spurious |
| 310 | # timeouts on AWS Lambda and other FaaS environments. |
| 311 | if remaining <= 0: |
| 312 | timed_out = True |
| 313 | timeout = max(min(remaining, _POLL_TIMEOUT), 0) |
| 314 | else: |
| 315 | timeout = _POLL_TIMEOUT |
| 316 | readable = conn.socket_checker.select(sock, read=True, timeout=timeout) |
| 317 | if conn.cancel_context.cancelled: |
| 318 | raise _OperationCancelled("operation cancelled") |
| 319 | if readable: |
| 320 | return |
| 321 | if timed_out: |
| 322 | raise socket.timeout("timed out") |
| 323 | |
| 324 | |
| 325 | def receive_data(conn: Connection, length: int, deadline: Optional[float]) -> memoryview: |
no test coverage detected