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

exarkun at twistedmatrix.com exarkun at twistedmatrix.com
Tue Sep 14 06:40:27 MDT 2010


On 12:29 pm, twisted-web at udmvt.ru wrote:
>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.

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.
>
>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?

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




More information about the Twisted-Python mailing list