[Twisted-Python] Just curious about EINTR in socket.recv()

As far as I know, socket.recv() may raise socket.error exception in case of error return from recv(2) system call. My system's (Linux i386 2.6.32) man page say there could be these error values: EAGAIN or EWOULDBLOCK EBADF ECONNREFUSED EFAULT EINTR EINVAL ENOMEM ENOTCONN ENOTSOCK Now, looking into twisted.internet.tcp, method doRead() on line 443, (twisted 10.1.0) we may find, that code: try: data = self.socket.recv(self.bufferSize) except socket.error, se: if se.args[0] == EWOULDBLOCK: return else: return main.CONNECTION_LOST if not data: return main.CONNECTION_DONE return self.protocol.dataReceived(data) This is the point in the twisted framework, that decides how TCP socket will get closed, whether that be in "clean" or "non clean" fashion. But some error codes, besides EWOULDBLOCK, are not in any way related to reporting a permanent error, that deserves closing the socket. Question to Python system library gurus: is socket.recv() supposed to raise socket.error with EINTR code ? In that case we should return None too, since that operation should be restarted, and reporting main.CONNECTION_LOST is a bug. What about ENOMEM case? Is system supposed to have destroyed the socket after that event, or it can safely recover later, so there is no sense in closing the socket in twisted either? Sorry, if that is a non-issue, or already tracked, I'm just curious. -- Alexey.

On 12:29 pm, twisted-web@udmvt.ru wrote:
This particular socket.recv call should not fail with EINTR because it is a non-blocking receive. If you know of a condition which contradicts this, please let us know.
Python will turn an ENOMEM into a raised MemoryError. In general in Python, it is challenging to do anything useful in response to a MemoryError. It may be possible to recover and continue using the socket, or it may not be, there's no way to know in general (and even knowing in a particular case can be challenging). So, without an idea of what would be a better way to handle MemoryError, Twisted typically treats it the same way it treats any other unexpected exception. It will generally get logged and if it came from a socket.recv() call like the one above, that socket will be disconnected and the associated protocol object informed. Jean-Paul

On 12:29 pm, twisted-web@udmvt.ru wrote:
This particular socket.recv call should not fail with EINTR because it is a non-blocking receive. If you know of a condition which contradicts this, please let us know.
Python will turn an ENOMEM into a raised MemoryError. In general in Python, it is challenging to do anything useful in response to a MemoryError. It may be possible to recover and continue using the socket, or it may not be, there's no way to know in general (and even knowing in a particular case can be challenging). So, without an idea of what would be a better way to handle MemoryError, Twisted typically treats it the same way it treats any other unexpected exception. It will generally get logged and if it came from a socket.recv() call like the one above, that socket will be disconnected and the associated protocol object informed. Jean-Paul
participants (2)
-
Alexey
-
exarkun@twistedmatrix.com