[Patches] [ python-Patches-1628205 ] socket.readline() interface doesn't handle EINTR properly

SourceForge.net noreply at sourceforge.net
Wed Mar 7 18:54:40 CET 2007


Patches item #1628205, was opened at 2007-01-04 16:37
Message generated for change (Comment added) made by jorend
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=305470&aid=1628205&group_id=5470

Please note that this message will contain a full copy of the comment thread,
including the initial issue submission, for this request,
not just the latest update.
Category: Modules
Group: None
Status: Open
Resolution: None
Priority: 5
Private: No
Submitted By: Maxim Sobolev (sobomax)
Assigned to: Nobody/Anonymous (nobody)
Summary: socket.readline() interface doesn't handle EINTR properly

Initial Comment:
The socket.readline() interface doesn't handle EINTR properly. Currently, when EINTR received exception is not handled and all data that has been in the buffer is lost. There is no way to recover that data from the code that uses the interface.

Correct behaviour would be to catch EINTR and restart recv(). Patch is attached.

Following is the real world example of how it affects httplib module:

  File "/usr/local/lib/python2.4/xmlrpclib.py", line 1096, in __call__
    return self.__send(self.__name, args)
  File "/usr/local/lib/python2.4/xmlrpclib.py", line 1383, in __request
    verbose=self.__verbose
  File "/usr/local/lib/python2.4/xmlrpclib.py", line 1131, in request
    errcode, errmsg, headers = h.getreply()
  File "/usr/local/lib/python2.4/httplib.py", line 1137, in getreply
    response = self._conn.getresponse()
  File "/usr/local/lib/python2.4/httplib.py", line 866, in getresponse
    response.begin()
  File "/usr/local/lib/python2.4/httplib.py", line 336, in begin
    version, status, reason = self._read_status()
  File "/usr/local/lib/python2.4/httplib.py", line 294, in _read_status
    line = self.fp.readline()
  File "/usr/local/lib/python2.4/socket.py", line 325, in readline
    data = recv(1)
error: (4, 'Interrupted system call')

-Maxim

----------------------------------------------------------------------

Comment By: Jason Orendorff (jorend)
Date: 2007-03-07 12:54

Message:
Logged In: YES 
user_id=18139
Originator: NO

loewis: I think your idea is the right answer.  I'm not worried about
select/poll.  Surely no one uses select/poll and
socket._fileobject.readline() on the same socket.  select/poll are for
nonblocking sockets; this readline() method doesn't even catch
EWOULDBLOCK.

...In fact even if you did use select/poll on the (blocking) socket after
readline() threw EINTR--which no one should do--I think it would still work
just as expected unless you were doing something truly weird.

----------------------------------------------------------------------

Comment By: Martin v. Löwis (loewis)
Date: 2007-02-16 08:05

Message:
Logged In: YES 
user_id=21627
Originator: NO

I agree that this should be fixed; I'm not sure I like the proposed fixed,
though. It discards the exception and keeps running.

What it (IMO) should do instead is abort, then return the data on the next
invocation. Of course, this may have problems in itself, since the file
descriptor might not report read-ready when passed to select or poll, even
though data are available.

Please discuss this on python-dev (and elsewhere), and report what
recommendations people made.

----------------------------------------------------------------------

Comment By: Maxim Sobolev (sobomax)
Date: 2007-01-08 05:51

Message:
Logged In: YES 
user_id=24670
Originator: YES

Well, it's not quite correct since for example httplib.py tries to handle
EINTR. The fundamental problem with socket.readline() is that it does
internal buffering so that getting EINTR results in data being lost.

I don't think it has to be fixed in C, since recv() is very low-level
interface and it is expected to return EINTR on signal, so that "fixing" it
there could possibly break software that relies on this behaviour. And I
don't quite buy your reasoning - "since it's broken in few more places
let's keep it consistently broken everywhere". To me it sounds like attempt
to hide the head in the sand instead of facing the problem at hand. Fixing
socket.readline() may be the first step in improvind the library to handle
this condition properly.

----------------------------------------------------------------------

Comment By: Oren Tirosh (orenti)
Date: 2007-01-07 13:24

Message:
Logged In: YES 
user_id=562624
Originator: NO

You may have encountered this on sockets but *all* Python I/O does not
handle restart on EINTR. 

The right place to fix this is probably in C, not the Python library. The
places where an I/O operation could be interrupted are practically anywhere
the GIL is released. This kind of change is likely to be controversial.


----------------------------------------------------------------------

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=305470&aid=1628205&group_id=5470


More information about the Patches mailing list