Author: Brian Kearns <[email protected]>
Branch: stdlib-2.7.6
Changeset: r69666:0c806895b514
Date: 2014-03-04 05:01 -0500
http://bitbucket.org/pypy/pypy/changeset/0c806895b514/
Log: handle eintr in _io module
diff --git a/pypy/module/_io/interp_bufferedio.py
b/pypy/module/_io/interp_bufferedio.py
--- a/pypy/module/_io/interp_bufferedio.py
+++ b/pypy/module/_io/interp_bufferedio.py
@@ -10,26 +10,13 @@
from rpython.rlib import rposix
from rpython.tool.sourcetools import func_renamer
from pypy.module._io.interp_iobase import (
- W_IOBase, DEFAULT_BUFFER_SIZE, convert_size,
+ W_IOBase, DEFAULT_BUFFER_SIZE, convert_size, trap_eintr,
check_readable_w, check_writable_w, check_seekable_w)
from pypy.module._io.interp_io import W_BlockingIOError
from rpython.rlib import rthread
-import errno
STATE_ZERO, STATE_OK, STATE_DETACHED = range(3)
-def trap_eintr(space, error):
- # Return True if an EnvironmentError with errno == EINTR is set
- if not error.match(space, space.w_EnvironmentError):
- return False
- try:
- w_value = error.get_w_value(space)
- w_errno = space.getattr(w_value, space.wrap("errno"))
- return space.is_true(
- space.eq(w_errno, space.wrap(errno.EINTR)))
- except OperationError:
- return False
-
def make_write_blocking_error(space, written):
w_type = space.gettypeobject(W_BlockingIOError.typedef)
@@ -58,7 +45,7 @@
raise self.operr
self.lock.acquire(True)
self.owner = rthread.get_ident()
-
+
def __exit__(self,*args):
self.owner = 0
self.lock.release()
diff --git a/pypy/module/_io/interp_fileio.py b/pypy/module/_io/interp_fileio.py
--- a/pypy/module/_io/interp_fileio.py
+++ b/pypy/module/_io/interp_fileio.py
@@ -390,10 +390,13 @@
try:
chunk = os.read(self.fd, newsize - total)
except OSError, e:
+ if e.errno == errno.EINTR:
+ space.getexecutioncontext().checksignals()
+ continue
+ if total > 0:
+ # return what we've got so far
+ break
if e.errno == errno.EAGAIN:
- if total > 0:
- # return what we've got so far
- break
return space.w_None
raise wrap_oserror(space, e,
exception_name='w_IOError')
diff --git a/pypy/module/_io/interp_iobase.py b/pypy/module/_io/interp_iobase.py
--- a/pypy/module/_io/interp_iobase.py
+++ b/pypy/module/_io/interp_iobase.py
@@ -1,3 +1,4 @@
+from errno import EINTR
from pypy.interpreter.baseobjspace import W_Root
from pypy.interpreter.error import OperationError, oefmt
from pypy.interpreter.typedef import (
@@ -16,6 +17,18 @@
else:
return space.int_w(w_size)
+def trap_eintr(space, error):
+ # Return True if an EnvironmentError with errno == EINTR is set
+ if not error.match(space, space.w_EnvironmentError):
+ return False
+ try:
+ w_value = error.get_w_value(space)
+ w_errno = space.getattr(w_value, space.wrap("errno"))
+ return space.is_true(
+ space.eq(w_errno, space.wrap(EINTR)))
+ except OperationError:
+ return False
+
def unsupported(space, message):
w_exc = space.getattr(space.getbuiltinmodule('_io'),
space.wrap('UnsupportedOperation'))
@@ -178,7 +191,12 @@
nreadahead = 1
if has_peek:
- w_readahead = space.call_method(self, "peek", space.wrap(1))
+ try:
+ w_readahead = space.call_method(self, "peek",
space.wrap(1))
+ except OperationError, e:
+ if trap_eintr(space, e):
+ continue
+ raise
if not space.isinstance_w(w_readahead, space.w_str):
raise oefmt(space.w_IOError,
"peek() should have returned a bytes object, "
@@ -203,7 +221,12 @@
break
nreadahead = n
- w_read = space.call_method(self, "read", space.wrap(nreadahead))
+ try:
+ w_read = space.call_method(self, "read",
space.wrap(nreadahead))
+ except OperationError, e:
+ if trap_eintr(space, e):
+ continue
+ raise
if not space.isinstance_w(w_read, space.w_str):
raise oefmt(space.w_IOError,
"peek() should have returned a bytes object, not "
@@ -254,7 +277,15 @@
if not e.match(space, space.w_StopIteration):
raise
break # done
- space.call_method(self, "write", w_line)
+ while True:
+ try:
+ space.call_method(self, "write", w_line)
+ except OperationError, e:
+ if trap_eintr(space, e):
+ continue
+ raise
+ else:
+ break
W_IOBase.typedef = TypeDef(
'_IOBase',
@@ -306,8 +337,13 @@
def readall_w(self, space):
builder = StringBuilder()
while True:
- w_data = space.call_method(self, "read",
- space.wrap(DEFAULT_BUFFER_SIZE))
+ try:
+ w_data = space.call_method(self, "read",
+ space.wrap(DEFAULT_BUFFER_SIZE))
+ except OperationError, e:
+ if trap_eintr(space, e):
+ continue
+ raise
if space.is_w(w_data, space.w_None):
if not builder.getlength():
return w_data
diff --git a/pypy/module/_io/interp_textio.py b/pypy/module/_io/interp_textio.py
--- a/pypy/module/_io/interp_textio.py
+++ b/pypy/module/_io/interp_textio.py
@@ -7,7 +7,7 @@
GetSetProperty, TypeDef, generic_new_descr, interp_attrproperty,
interp_attrproperty_w)
from pypy.module._codecs import interp_codecs
-from pypy.module._io.interp_iobase import W_IOBase, convert_size
+from pypy.module._io.interp_iobase import W_IOBase, convert_size, trap_eintr
from rpython.rlib.rarithmetic import intmask, r_uint, r_ulonglong
from rpython.rlib.rbigint import rbigint
from rpython.rlib.rstring import UnicodeBuilder
@@ -614,9 +614,14 @@
if remaining <= 0: # Done
break
- if not self._read_chunk(space):
- # EOF
- break
+ try:
+ if not self._read_chunk(space):
+ # EOF
+ break
+ except OperationError, e:
+ if trap_eintr(space, e):
+ continue
+ raise
return space.wrap(builder.build())
@@ -635,9 +640,14 @@
# First, get some data if necessary
has_data = True
while not self.decoded_chars:
- if not self._read_chunk(space):
- has_data = False
- break
+ try:
+ if not self._read_chunk(space):
+ has_data = False
+ break
+ except OperationError, e:
+ if trap_eintr(space, e):
+ continue
+ raise
if not has_data:
# end of file
self._set_decoded_chars(None)
@@ -772,7 +782,15 @@
self.pending_bytes = None
self.pending_bytes_count = 0
- space.call_method(self.w_buffer, "write", space.wrap(pending_bytes))
+ while True:
+ try:
+ space.call_method(self.w_buffer, "write",
space.wrap(pending_bytes))
+ except OperationError, e:
+ if trap_eintr(space, e):
+ continue
+ raise
+ else:
+ break
def detach_w(self, space):
self._check_init(space)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit