| 298 | ConnectionShutdown("Connection to %s was closed" % self.endpoint)) |
| 299 | |
| 300 | def handle_write(self, watcher, revents, errno=None): |
| 301 | if revents & libev.EV_ERROR: |
| 302 | if errno: |
| 303 | exc = IOError(errno, os.strerror(errno)) |
| 304 | else: |
| 305 | exc = Exception("libev reported an error") |
| 306 | |
| 307 | self.defunct(exc) |
| 308 | return |
| 309 | |
| 310 | while True: |
| 311 | try: |
| 312 | with self._deque_lock: |
| 313 | next_msg = self.deque.popleft() |
| 314 | except IndexError: |
| 315 | if not self._socket_writable: |
| 316 | self._socket_writable = True |
| 317 | return |
| 318 | |
| 319 | try: |
| 320 | sent = self._socket.send(next_msg) |
| 321 | except socket.error as err: |
| 322 | if (err.args[0] in NONBLOCKING or |
| 323 | err.args[0] in (ssl.SSL_ERROR_WANT_READ, ssl.SSL_ERROR_WANT_WRITE)): |
| 324 | if err.args[0] in NONBLOCKING: |
| 325 | self._socket_writable = False |
| 326 | with self._deque_lock: |
| 327 | self.deque.appendleft(next_msg) |
| 328 | else: |
| 329 | self.defunct(err) |
| 330 | return |
| 331 | else: |
| 332 | if sent < len(next_msg): |
| 333 | with self._deque_lock: |
| 334 | self.deque.appendleft(next_msg[sent:]) |
| 335 | # we've seen some cases that 0 is returned instead of NONBLOCKING. But usually, |
| 336 | # we don't expect this to happen. https://bugs.python.org/issue20951 |
| 337 | if sent == 0: |
| 338 | self._socket_writable = False |
| 339 | return |
| 340 | |
| 341 | def handle_read(self, watcher, revents, errno=None): |
| 342 | if revents & libev.EV_ERROR: |