Adds `state` (IOLoop.{READ,WRITE} flags) to our event handler. Implementation notes: Reads and writes have a fast path and a slow path. The fast path reads synchronously from socket buffers, while the slow path uses `_add_io_state` to schedule an IOLoop callback.
(self, state: int)
| 1013 | self._add_io_state(ioloop.IOLoop.READ) |
| 1014 | |
| 1015 | def _add_io_state(self, state: int) -> None: |
| 1016 | """Adds `state` (IOLoop.{READ,WRITE} flags) to our event handler. |
| 1017 | |
| 1018 | Implementation notes: Reads and writes have a fast path and a |
| 1019 | slow path. The fast path reads synchronously from socket |
| 1020 | buffers, while the slow path uses `_add_io_state` to schedule |
| 1021 | an IOLoop callback. |
| 1022 | |
| 1023 | To detect closed connections, we must have called |
| 1024 | `_add_io_state` at some point, but we want to delay this as |
| 1025 | much as possible so we don't have to set an `IOLoop.ERROR` |
| 1026 | listener that will be overwritten by the next slow-path |
| 1027 | operation. If a sequence of fast-path ops do not end in a |
| 1028 | slow-path op, (e.g. for an @asynchronous long-poll request), |
| 1029 | we must add the error handler. |
| 1030 | |
| 1031 | TODO: reevaluate this now that callbacks are gone. |
| 1032 | |
| 1033 | """ |
| 1034 | if self.closed(): |
| 1035 | # connection has been closed, so there can be no future events |
| 1036 | return |
| 1037 | if self._state is None: |
| 1038 | self._state = ioloop.IOLoop.ERROR | state |
| 1039 | self.io_loop.add_handler(self.fileno(), self._handle_events, self._state) |
| 1040 | elif not self._state & state: |
| 1041 | self._state = self._state | state |
| 1042 | self.io_loop.update_handler(self.fileno(), self._state) |
| 1043 | |
| 1044 | def _is_connreset(self, exc: BaseException) -> bool: |
| 1045 | """Return ``True`` if exc is ECONNRESET or equivalent. |
no test coverage detected