[pypy-commit] pypy stdlib-2.7.6: handle eintr in multiprocessing
bdkearns
noreply at buildbot.pypy.org
Tue Mar 4 02:21:09 CET 2014
Author: Brian Kearns <bdkearns at gmail.com>
Branch: stdlib-2.7.6
Changeset: r69648:69c907ade980
Date: 2014-03-03 20:19 -0500
http://bitbucket.org/pypy/pypy/changeset/69c907ade980/
Log: handle eintr in multiprocessing
diff --git a/pypy/module/_multiprocessing/interp_connection.py b/pypy/module/_multiprocessing/interp_connection.py
--- a/pypy/module/_multiprocessing/interp_connection.py
+++ b/pypy/module/_multiprocessing/interp_connection.py
@@ -1,4 +1,5 @@
import sys
+from errno import EINTR
from rpython.rlib import rpoll, rsocket
from rpython.rlib.rarithmetic import intmask
@@ -306,6 +307,9 @@
try:
count = self.WRITE(data)
except OSError, e:
+ if e.errno == EINTR:
+ space.getexecutioncontext().checksignals()
+ continue
raise wrap_oserror(space, e)
size -= count
message = rffi.ptradd(message, count)
@@ -317,6 +321,9 @@
try:
data = self.READ(remaining)
except OSError, e:
+ if e.errno == EINTR:
+ space.getexecutioncontext().checksignals()
+ continue
raise wrap_oserror(space, e)
count = len(data)
if count == 0:
@@ -340,10 +347,8 @@
def do_poll(self, space, timeout):
if not self._check_fd():
- raise OperationError(space.w_IOError, space.wrap(
- "handle out of range in select()"))
-
- r, w, e = rpoll.select([self.fd], [], [], timeout)
+ raise oefmt(space.w_IOError, "handle out of range in select()")
+ r, w, e = rpoll.select([self.fd], [], [], timeout, handle_eintr=True)
return bool(r)
W_FileConnection.typedef = TypeDef(
diff --git a/rpython/rlib/_rsocket_rffi.py b/rpython/rlib/_rsocket_rffi.py
--- a/rpython/rlib/_rsocket_rffi.py
+++ b/rpython/rlib/_rsocket_rffi.py
@@ -1,4 +1,3 @@
-
from rpython.rtyper.lltypesystem import rffi
from rpython.rtyper.lltypesystem import lltype
from rpython.rtyper.tool import rffi_platform as platform
@@ -40,7 +39,7 @@
'net/if.h')
cond_includes = [('AF_NETLINK', 'linux/netlink.h')]
-
+
libraries = ()
calling_conv = 'c'
HEADER = ''.join(['#include <%s>\n' % filename for filename in includes])
@@ -612,11 +611,11 @@
WSAPROTOCOL_INFO = cConfig.WSAPROTOCOL_INFO
FROM_PROTOCOL_INFO = cConfig.FROM_PROTOCOL_INFO
- WSADuplicateSocket = external('WSADuplicateSocketA',
+ WSADuplicateSocket = external('WSADuplicateSocketA',
[socketfd_type, rwin32.DWORD,
lltype.Ptr(WSAPROTOCOL_INFO)],
rffi.INT)
- WSASocket = external('WSASocketA',
+ WSASocket = external('WSASocketA',
[rffi.INT, rffi.INT, rffi.INT,
lltype.Ptr(WSAPROTOCOL_INFO),
rwin32.DWORD, rwin32.DWORD],
diff --git a/rpython/rlib/rpoll.py b/rpython/rlib/rpoll.py
--- a/rpython/rlib/rpoll.py
+++ b/rpython/rlib/rpoll.py
@@ -5,6 +5,7 @@
function that directly takes a dictionary as argument.
"""
+from errno import EINTR
from rpython.rlib import _rsocket_rffi as _c
from rpython.rlib.rarithmetic import r_uint
from rpython.rtyper.lltypesystem import lltype, rffi
@@ -71,9 +72,9 @@
lltype.free(pollfds, flavor='raw')
return retval
-def select(inl, outl, excl, timeout=-1.0):
+def select(inl, outl, excl, timeout=-1.0, handle_eintr=False):
nfds = 0
- if inl:
+ if inl:
ll_inl = lltype.malloc(_c.fd_set.TO, flavor='raw')
_c.FD_ZERO(ll_inl)
for i in inl:
@@ -82,7 +83,7 @@
nfds = i
else:
ll_inl = lltype.nullptr(_c.fd_set.TO)
- if outl:
+ if outl:
ll_outl = lltype.malloc(_c.fd_set.TO, flavor='raw')
_c.FD_ZERO(ll_outl)
for i in outl:
@@ -91,7 +92,7 @@
nfds = i
else:
ll_outl = lltype.nullptr(_c.fd_set.TO)
- if excl:
+ if excl:
ll_excl = lltype.malloc(_c.fd_set.TO, flavor='raw')
_c.FD_ZERO(ll_excl)
for i in excl:
@@ -100,15 +101,23 @@
nfds = i
else:
ll_excl = lltype.nullptr(_c.fd_set.TO)
- if timeout != -1.0:
+
+ if timeout < 0:
+ ll_timeval = lltype.nullptr(_c.timeval)
+ while True:
+ res = _c.select(nfds + 1, ll_inl, ll_outl, ll_excl, ll_timeval)
+ if not handle_eintr or res >= 0 or _c.geterrno() != EINTR:
+ break
+ else:
+ sec = int(timeout)
+ usec = int((timeout - sec) * 10**6)
ll_timeval = rffi.make(_c.timeval)
- rffi.setintfield(ll_timeval, 'c_tv_sec', int(timeout))
- rffi.setintfield(ll_timeval, 'c_tv_usec', int((timeout-int(timeout))
- * 1000000))
- else:
- ll_timeval = lltype.nullptr(_c.timeval)
+ rffi.setintfield(ll_timeval, 'c_tv_sec', sec)
+ rffi.setintfield(ll_timeval, 'c_tv_usec', usec)
+ res = _c.select(nfds + 1, ll_inl, ll_outl, ll_excl, ll_timeval)
+ if handle_eintr and res < 0 and _c.geterrno() == EINTR:
+ res = 0 # interrupted, act as timed out
try:
- res = _c.select(nfds + 1, ll_inl, ll_outl, ll_excl, ll_timeval)
if res == -1:
raise SelectError(_c.geterrno())
if res == 0:
More information about the pypy-commit
mailing list