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

Reply via email to