[Python-Dev] RFC: PEP 475, Retry system calls failing with EINTR
R. David Murray
rdmurray at bitdance.com
Mon Sep 1 06:51:25 CEST 2014
On Sun, 31 Aug 2014 20:14:50 -0700, Dan Stromberg <drsalists at gmail.com> wrote:
> On Sun, Aug 31, 2014 at 3:28 PM, Greg Ewing <greg.ewing at canterbury.ac.nz> wrote:
> > Victor Stinner wrote:
> >>
> >> As written in the PEP, if you want to be notified of the signal, set a
> >> signal handler which raises an exception.
> >
> > I'm not convinced that this covers all possible use cases.
> > It might be all right if you have control over the signal
> > handler, but what if you don't?
> >
> > I think it's best if the functions in the os module remain
> > thin wrappers that expose the OS functionality as fully and
> > directly as possible. Anything else should be provided
> > by higher-level facilities.
>
> I'm inclined to agree about keeping the os module thin. If we were to
> recreate Python today, from scratch, it might make sense to hide this
> by default, but now there's almost certainly code out there that
> depends on the current behavior.
>
> But I also agree that it's hard to pin down which higher level Python
> library calls are going to be using system calls. My
> http://stromberg.dnsalias.org/~strombrg/pypty/ program had a problem
> with window resizing for a while (SIGWINCH), and although I use it
> pretty much daily now without problems, I'm still not sure I got 100%
> of the possibilities covered.
>
> Fortunately, wrapping a system call can be as simple as:
>
> def retry_on_eintr(function, *args, **kw):
> '''
> Retry a system call until one of the following happens:
> 1) It succeeds
> 2) It errors with something other than EINTR
> '''
>
> while True:
> try:
> return function(*args, **kw)
> except OSError:
> nothing, extra, nothing2 = sys.exc_info()
> dummy = nothing
> dummy = nothing2
> if extra.errno == errno.EINTR:
> continue
> else:
> raise
>
> Note that os.read() and os.write() need different handling.
Personally, I really want Python to handle EINTR for me. And indeed,
that has been what we have been doing for a while now, piece by piece,
bug by bug. Victor just wants to systematize and document that, and I
think that's a good idea.
We've been consistently treating lack of handling of EINTR as a bug.
If there are *real* cases where that causes a backward compatibility
problem, then we need to know. But so far, we have gotten zero
complaints about the cases that we have fixed.
--David
PS: I recently switched from using selectors to using a timeout on a
socket because in that particular application I could, and because
reading a socket with a timeout handles EINTR (in recent python
versions), whereas reading a non-blocking socket doesn't. Under the
hood, a socket with a timeout is a non-blocking socket.
More information about the Python-Dev
mailing list