diff options
author | Guido van Rossum <guido@dropbox.com> | 2013-11-01 21:12:50 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@dropbox.com> | 2013-11-01 21:12:50 (GMT) |
commit | 3317a1325385a6b7a4a208e0d00c43e9e8ac562e (patch) | |
tree | 495eec1e8c8d00e1e8238ca4bd2f1d1ff58bb77a /Lib/asyncio/selector_events.py | |
parent | 2b8fc303ad60894bf76b76f82e774b2c7e9f1702 (diff) | |
download | cpython-3317a1325385a6b7a4a208e0d00c43e9e8ac562e.zip cpython-3317a1325385a6b7a4a208e0d00c43e9e8ac562e.tar.gz cpython-3317a1325385a6b7a4a208e0d00c43e9e8ac562e.tar.bz2 |
asyncio: Pause accepting whenever accept() returns certain errors. Fixes asyncio issue #78.
Diffstat (limited to 'Lib/asyncio/selector_events.py')
-rw-r--r-- | Lib/asyncio/selector_events.py | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py index c296dcc..f7bc61a 100644 --- a/Lib/asyncio/selector_events.py +++ b/Lib/asyncio/selector_events.py @@ -5,6 +5,7 @@ also includes support for signal handling, see the unix_events sub-module. """ import collections +import errno import socket try: import ssl @@ -98,15 +99,23 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop): try: conn, addr = sock.accept() conn.setblocking(False) - except (BlockingIOError, InterruptedError): + except (BlockingIOError, InterruptedError, ConnectionAbortedError): pass # False alarm. - except Exception: - # Bad error. Stop serving. - self.remove_reader(sock.fileno()) - sock.close() + except OSError as exc: # There's nowhere to send the error, so just log it. # TODO: Someone will want an error handler for this. - logger.exception('Accept failed') + if exc.errno in (errno.EMFILE, errno.ENFILE, + errno.ENOBUFS, errno.ENOMEM): + # Some platforms (e.g. Linux keep reporting the FD as + # ready, so we remove the read handler temporarily. + # We'll try again in a while. + logger.exception('Accept out of system resource (%s)', exc) + self.remove_reader(sock.fileno()) + self.call_later(constants.ACCEPT_RETRY_DELAY, + self._start_serving, + protocol_factory, sock, ssl, server) + else: + raise # The event loop will catch, log and ignore it. else: if ssl: self._make_ssl_transport( |