[pypy-commit] pypy py3.5-sendmsg-recvmsg: Fix for the test_EINTR errors on sendmsg and recvmsg
Dodan
pypy.commits at gmail.com
Tue Aug 1 09:12:58 EDT 2017
Author: Dodan Mihai <mihai.dodan at gmail.com>
Branch: py3.5-sendmsg-recvmsg
Changeset: r92014:a8d5fdebbce7
Date: 2017-08-01 16:11 +0300
http://bitbucket.org/pypy/pypy/changeset/a8d5fdebbce7/
Log: Fix for the test_EINTR errors on sendmsg and recvmsg
diff --git a/pypy/module/_socket/interp_socket.py b/pypy/module/_socket/interp_socket.py
--- a/pypy/module/_socket/interp_socket.py
+++ b/pypy/module/_socket/interp_socket.py
@@ -473,27 +473,27 @@
raise oefmt(space.w_ValueError, "negative buffer size in recvmsg()")
if ancbufsize < 0:
raise oefmt(space.w_ValueError, "invalid ancillary data buffer length")
- try:
- tuple = self.sock.recvmsg(message_size, ancbufsize, flags)
- message = space.newbytes(tuple[0])
- # print(tuple[0])
- list = []
- for l in tuple[1]:
- tup = space.newtuple([space.newint(l[0]), space.newint(l[1]), space.newbytes(l[2])])
- list.append(tup)
+ while True:
+ try:
+ tuple = self.sock.recvmsg(message_size, ancbufsize, flags)
+ message = space.newbytes(tuple[0])
+ list = []
+ for l in tuple[1]:
+ tup = space.newtuple([space.newint(l[0]), space.newint(l[1]), space.newbytes(l[2])])
+ list.append(tup)
- anc = space.newlist(list)
+ anc = space.newlist(list)
- flag = space.newint(tuple[2])
- if (tuple[3] is not None):
- address = addr_as_object(tuple[3], self.sock.fd, space)
- else:
- address = space.w_None
-
- rettup = space.newtuple([message, anc, flag, address])
- return rettup
- except SocketError as e:
- converted_error(space, e, eintr_retry=True)
+ flag = space.newint(tuple[2])
+ if (tuple[3] is not None):
+ address = addr_as_object(tuple[3], self.sock.fd, space)
+ else:
+ address = space.w_None
+ rettup = space.newtuple([message, anc, flag, address])
+ break
+ except SocketError as e:
+ converted_error(space, e, eintr_retry=True)
+ return rettup
@unwrap_spec(data='bufferstr', flags=int)
def send_w(self, space, data, flags=0):
@@ -566,110 +566,117 @@
:return: Bytes sent from the message
"""
# Get the flag and address from the object space
- flags = 0
- if space.is_none(w_flags) is False:
- flags = space.int_w(w_flags)
+ while True:
+ try:
+ flags = 0
+ if space.is_none(w_flags) is False:
+ flags = space.int_w(w_flags)
- address = None
- if space.is_none(w_address) is False:
- address = self.addr_from_object(space, w_address)
+ address = None
+ if space.is_none(w_address) is False:
+ address = self.addr_from_object(space, w_address)
- # find data's type in the ObjectSpace and get a list of string out of it.
- data = []
- if (w_data.typedef.name == 'list'):
- for i in w_data.getitems():
- if space.isinstance_w(i,space.w_bytes):
- data.append(space.bytes_w(i))
+ # find data's type in the ObjectSpace and get a list of string out of it.
+ data = []
+ if (w_data.typedef.name == 'list'):
+ for i in w_data.getitems():
+ if space.isinstance_w(i, space.w_bytes):
+ data.append(space.bytes_w(i))
+ else:
+ if (i.typedef.name == 'array.array'):
+ data.append(space.bytes_w(i.descr_tobytes(space)))
+ else:
+ if (i.typedef.name == 'memoryview'):
+ data.append(space.bytes_w(i.descr_tobytes(space)))
+ else:
+ raise oefmt(space.w_TypeError, "a bytes-like object is required")
else:
- if (i.typedef.name == 'array.array'):
- data.append(space.bytes_w(i.descr_tobytes(space)))
+ while True:
+ try:
+ if (space.is_generator(w_data) is False):
+ raise oefmt(space.w_TypeError, "sendmsg(): argument 1 must be iterable")
+ i = space.next(w_data)
+ if space.isinstance_w(i, space.w_bytes):
+ data.append(space.bytes_w(i))
+ else:
+ if (i.typedef.name == 'array.array'):
+ data.append(space.bytes_w(i.descr_tobytes(space)))
+ else:
+ if (i.typedef.name == 'memoryview'):
+ data.append(space.bytes_w(i.descr_tobytes(space)))
+ else:
+ raise oefmt(space.w_TypeError, "a bytes-like object is required")
+ except OperationError as e:
+ if not e.match(space, space.w_StopIteration):
+ raise
+ break
+
+ # find the ancillary's type in the ObjectSpace and get a list of tuples out of it.
+ ancillary = []
+ if w_ancillary is not None:
+ if (space.isinstance_w(w_ancillary, space.w_list)):
+ for i in w_ancillary.getitems():
+ if (space.isinstance_w(i, space.w_tuple) is False):
+ raise oefmt(space.w_TypeError, "[sendmsg() ancillary data items]() argument must be sequence")
+ if (space.len_w(i) == 3):
+ level = space.int_w(space.getitem(i, space.newint(0)))
+ type = space.int_w(space.getitem(i, space.newint(1)))
+ if (space.getitem(i, space.newint(2)).typedef.name == 'array.array'):
+ cont = space.bytes_w(space.getitem(i, space.newint(2)).descr_tobytes(space))
+ else:
+ if (space.isinstance_w(space.getitem(i, space.newint(2)), space.w_bytes)):
+ cont = space.bytes_w(space.getitem(i, space.newint(2)))
+ else:
+ raise oefmt(space.w_TypeError, "a bytes-like object is required")
+ tup = (level, type, cont)
+ ancillary.append(tup)
+ else:
+ raise oefmt(space.w_TypeError,
+ "[sendmsg() ancillary data items]() argument must be sequence of length 3")
+
else:
- raise oefmt(space.w_TypeError, "a bytes-like object is required")
- else:
- while True:
- try:
- if (space.is_generator(w_data) is False):
- raise oefmt(space.w_TypeError, "sendmsg(): argument 1 must be iterable")
- i = space.next(w_data)
- if space.isinstance_w(i, space.w_bytes):
- data.append(space.bytes_w(i))
- else:
- if (i.typedef.name == 'array.array'):
- data.append(space.bytes_w(i.descr_tobytes(space)))
- else:
- raise oefmt(space.w_TypeError, "a bytes-like object is required")
- except OperationError as e:
- if not e.match(space,space.w_StopIteration):
- raise
- break
+ while True:
+ try:
+ if (space.is_generator(w_ancillary) is False):
+ raise oefmt(space.w_TypeError,
+ "[sendmsg() ancillary data items]() argument must be sequence")
+ i = space.next(w_ancillary)
+ if (space.isinstance_w(i, space.w_tuple) is False):
+ raise oefmt(space.w_TypeError,
+ "[sendmsg() ancillary data items]() argument must be sequence of length 3")
+ if (space.len_w(i) != 3):
+ raise oefmt(space.w_TypeError,
+ "[sendmsg() ancillary data items]() argument must be sequence of length 3")
+ except OperationError as e:
+ if not e.match(space, space.w_StopIteration):
+ raise
+ break
+ level = space.int_w(space.getitem(i, space.newint(0)))
+ type = space.int_w(space.getitem(i, space.newint(1)))
+ if (space.getitem(i, space.newint(2)).typedef.name == 'array.array'):
+ cont = space.bytes_w(space.getitem(i, space.newint(2)).descr_tobytes(space))
+ else:
+ if (space.isinstance_w(space.getitem(i, space.newint(2)), space.w_bytes)):
+ cont = space.bytes_w(space.getitem(i, space.newint(2)))
+ else:
+ raise oefmt(space.w_TypeError, "a bytes-like object is required")
+ tup = (level, type, cont)
+ ancillary.append(tup)
- # find the ancillary's type in the ObjectSpace and get a list of tuples out of it.
- ancillary = []
- if w_ancillary is not None:
- if (space.isinstance_w(w_ancillary,space.w_list)):
- for i in w_ancillary.getitems():
- if (space.isinstance_w(i, space.w_tuple) is False):
- raise oefmt(space.w_TypeError,"[sendmsg() ancillary data items]() argument must be sequence")
- if (space.len_w(i) == 3):
- level = space.int_w(space.getitem(i, space.newint(0)))
- type = space.int_w(space.getitem(i, space.newint(1)))
- if (space.getitem(i, space.newint(2)).typedef.name == 'array.array'):
- cont = space.bytes_w(space.getitem(i, space.newint(2)).descr_tobytes(space))
- else:
- if (space.isinstance_w(space.getitem(i, space.newint(2)), space.w_bytes)):
- cont = space.bytes_w(space.getitem(i, space.newint(2)))
- else:
- raise oefmt(space.w_TypeError,"a bytes-like object is required")
- tup = (level, type, cont)
- ancillary.append(tup)
- else:
- raise oefmt(space.w_TypeError,
- "[sendmsg() ancillary data items]() argument must be sequence of length 3")
- else:
- while True:
- try:
- if (space.is_generator(w_ancillary) is False):
- raise oefmt(space.w_TypeError,
- "[sendmsg() ancillary data items]() argument must be sequence")
- i = space.next(w_ancillary)
- if (space.isinstance_w(i, space.w_tuple) is False):
- raise oefmt(space.w_TypeError,
- "[sendmsg() ancillary data items]() argument must be sequence of length 3")
- if (space.len_w(i) != 3):
- raise oefmt(space.w_TypeError,
- "[sendmsg() ancillary data items]() argument must be sequence of length 3")
- except OperationError as e:
- if not e.match(space,space.w_StopIteration):
- raise
- break
- level = space.int_w(space.getitem(i, space.newint(0)))
- type = space.int_w(space.getitem(i, space.newint(1)))
- if (space.getitem(i, space.newint(2)).typedef.name == 'array.array'):
- cont = space.bytes_w(space.getitem(i, space.newint(2)).descr_tobytes(space))
- else:
- if (space.isinstance_w(space.getitem(i, space.newint(2)), space.w_bytes)):
- cont = space.bytes_w(space.getitem(i, space.newint(2)))
- else:
- raise oefmt(space.w_TypeError, "a bytes-like object is required")
- tup = (level, type, cont)
- ancillary.append(tup)
+ count = self.sock.sendmsg(data, ancillary, flags, address)
+ if count < 0:
+ if (count == -1000):
+ raise oefmt(space.w_OSError, "sending multiple control messages not supported")
+ if (count == -1001):
+ raise oefmt(space.w_OSError, "ancillary data item too large")
+ if (count == -1002):
+ raise oefmt(space.w_OSError, "too much ancillary data")
+ break
+ except SocketError as e:
+ converted_error(space, e, eintr_retry=True)
- try:
- count = self.sock.sendmsg(data, ancillary, flags, address)
- if count < 0:
- if (count == -1000):
- raise oefmt(space.w_OSError, "sending multiple control messages not supported")
- if (count == -1001):
- raise oefmt(space.w_OSError, "ancillary data item too large")
- if (count == -1002):
- raise oefmt(space.w_OSError, "too much ancillary data")
-
- return space.newint(count)
- except SocketError as e:
- converted_error(space, e, eintr_retry=True)
-
-
+ return space.newint(count)
@unwrap_spec(flag=int)
def setblocking_w(self, flag):
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
@@ -514,15 +514,15 @@
int flags,
struct sockaddr* address,
socklen_t* addrlen,
- int** length_of_messages,
+ long** length_of_messages,
char** messages,
- int* no_of_messages,
- int* size_of_ancillary,
+ long* no_of_messages,
+ long* size_of_ancillary,
long** levels,
long** types,
char** file_descr,
long** descr_per_ancillary,
- int* retflag)
+ long* retflag)
{
@@ -629,13 +629,15 @@
*addrlen = retinfo->addrlen;
// Set the parameters of message
- *no_of_messages = retinfo->no_of_messages;
- *size_of_ancillary = retinfo->size_of_ancillary;
- *length_of_messages = (int*) malloc (sizeof(int) * retinfo->no_of_messages);
- memcpy(*length_of_messages, retinfo->length_of_messages, sizeof(int) * retinfo->no_of_messages);
+ no_of_messages[0] = retinfo->no_of_messages;
+ size_of_ancillary[0] = retinfo->size_of_ancillary;
+ *length_of_messages = (long*) malloc (sizeof(long) * retinfo->no_of_messages);
+ //memcpy(*length_of_messages, retinfo->length_of_messages, sizeof(int) * retinfo->no_of_messages);
int counter = 0;
- for (i=0; i< retinfo->no_of_messages; i++)
+ for (i=0; i< retinfo->no_of_messages; i++){
counter += retinfo->length_of_messages[i];
+ length_of_messages[0][i] = retinfo->length_of_messages[i];
+ }
memset(*messages, 0, sizeof(char) * counter);
counter = 0;
for(i=0; i< retinfo->no_of_messages; i++){
@@ -664,7 +666,7 @@
}
// Set the retflag
- *retflag = retinfo->retflag;
+ retflag[0] = retinfo->retflag;
// Free the memory
free(retinfo->address);
@@ -959,7 +961,7 @@
post_include_bits =[ "RPY_EXTERN "
"int sendmsg_implementation(int socket, struct sockaddr* address, socklen_t addrlen, long* length_of_messages, char** messages, int no_of_messages, long* levels, long* types, char** file_descriptors, long* no_of_fds, int control_length, int flag );\n"
"RPY_EXTERN "
- "int recvmsg_implementation(int socket_fd, int message_size, int ancillary_size, int flags, struct sockaddr* address, socklen_t* addrlen, int** length_of_messages, char** messages, int* no_of_messages, int* size_of_ancillary, long** levels, long** types, char** file_descr, long** descr_per_ancillary, int* flag);\n"
+ "int recvmsg_implementation(int socket_fd, int message_size, int ancillary_size, int flags, struct sockaddr* address, socklen_t* addrlen, long** length_of_messages, char** messages, long* no_of_messages, long* size_of_ancillary, long** levels, long** types, char** file_descr, long** descr_per_ancillary, long* flag);\n"
"static "
"int cmsg_min_space(struct msghdr *msg, struct cmsghdr *cmsgh, size_t space);\n"
"static "
diff --git a/rpython/rlib/rsocket.py b/rpython/rlib/rsocket.py
--- a/rpython/rlib/rsocket.py
+++ b/rpython/rlib/rsocket.py
@@ -932,7 +932,6 @@
address.addrlen = addrlen
else:
address = None
- print address
data = buf.str(read_bytes)
return (data, address)
raise self.error_handler()
@@ -997,7 +996,7 @@
retflag[0] = rffi.cast(rffi.SIGNED,0)
# a mask for the SIGNEDP's that need to be cast to int. (long default)
- LONG_MASK = 2**32 - 1
+ #LONG_MASK = 2**32 - 1
reply = _c.recvmsg(self.fd, rffi.cast(lltype.Signed,message_size),
rffi.cast(lltype.Signed,ancbufsize),rffi.cast(lltype.Signed,flags),
addr_p, addrlen_p, len_of_msgs, messages, no_of_messages,size_of_anc,
@@ -1011,7 +1010,7 @@
for i in range(msg_no):
x = rffi.cast(rffi.SIGNED,len_of_msgs[0][i])
- x &= LONG_MASK
+ #x &= LONG_MASK
retmsg = rffi.charp2strn(messages[0],x)
offset = 0
@@ -1078,6 +1077,8 @@
if address is not None:
address.unlock()
+ if _c.geterrno() == _c.EINTR:
+ raise last_error()
if (reply == -10000):
raise RSocketError("Invalid message size")
if (reply == -10001):
More information about the pypy-commit
mailing list