diff --git a/Doc/library/asyncore.rst b/Doc/library/asyncore.rst --- a/Doc/library/asyncore.rst +++ b/Doc/library/asyncore.rst @@ -209,6 +209,8 @@ Read at most *buffer_size* bytes from the socket's remote end-point. An empty string implies that the channel has been closed from the other end. + Note that *recv* may raise OSError with EWOULDBLOCK or EAGAIN, even + though select has reported the socket ready for reading. .. method:: listen(backlog) diff --git a/Lib/asynchat.py b/Lib/asynchat.py --- a/Lib/asynchat.py +++ b/Lib/asynchat.py @@ -48,7 +48,9 @@ import socket import asyncore from collections import deque +from errno import EWOULDBLOCK, EAGAIN +_RETRY = frozenset((EWOULDBLOCK, EAGAIN)) class async_chat (asyncore.dispatcher): """This is an abstract class. You must derive from this class, and add @@ -115,7 +117,8 @@ try: data = self.recv (self.ac_in_buffer_size) except OSError as why: - self.handle_error() + if why.args[0] not in _RETRY: + self.handle_error() return if isinstance(data, str) and self.use_encoding: