| 1139 | |
| 1140 | # For C style IO handler need to implement Selector |
| 1141 | class IOHandler(Handler): |
| 1142 | |
| 1143 | def __init__(self) -> None: |
| 1144 | self._selector = IO.Selector() |
| 1145 | |
| 1146 | def on_selectable_init(self, event: Event) -> None: |
| 1147 | s = event.selectable |
| 1148 | self._selector.add(s) |
| 1149 | s._reactor._selectables += 1 |
| 1150 | |
| 1151 | def on_selectable_updated(self, event: Event) -> None: |
| 1152 | s = event.selectable |
| 1153 | self._selector.update(s) |
| 1154 | |
| 1155 | def on_selectable_final(self, event: Event) -> None: |
| 1156 | s = event.selectable |
| 1157 | self._selector.remove(s) |
| 1158 | s._reactor._selectables -= 1 |
| 1159 | s.close() |
| 1160 | |
| 1161 | def on_reactor_quiesced(self, event: Event) -> None: |
| 1162 | r = event.reactor |
| 1163 | |
| 1164 | if not r.quiesced: |
| 1165 | return |
| 1166 | |
| 1167 | r.timer_deadline |
| 1168 | readable, writable, expired = self._selector.select(r.timeout) |
| 1169 | |
| 1170 | r.mark() |
| 1171 | |
| 1172 | for s in readable: |
| 1173 | s.readable() |
| 1174 | for s in writable: |
| 1175 | s.writable() |
| 1176 | for s in expired: |
| 1177 | s.expired() |
| 1178 | |
| 1179 | r.yield_() |
| 1180 | |
| 1181 | def on_selectable_readable(self, event: Event) -> None: |
| 1182 | s = event.selectable |
| 1183 | t = s._transport |
| 1184 | |
| 1185 | # If we're an acceptor we can't have a transport |
| 1186 | # and we don't want to do anything here in any case |
| 1187 | if not t: |
| 1188 | return |
| 1189 | |
| 1190 | capacity = t.capacity() |
| 1191 | if capacity > 0: |
| 1192 | try: |
| 1193 | b = s.recv(capacity) |
| 1194 | if len(b) > 0: |
| 1195 | t.push(b) |
| 1196 | else: |
| 1197 | # EOF handling |
| 1198 | self.on_selectable_error(event) |