greenio: Remove sendall-like semantincs from GreenSocket.send
When a socket timeout was set the sendall-like semantics was resulting in losing information about sent data and raising socket.timeout exception. The previous GreenSocket.send() implementation used to call fd.send() in a loop until all data was sent. The issue would manifest if at least one fd.send() call succeeded and was followed by a fd.send() call that would block and a trampoline that timed out. The client code would see socket.timeout being raised and would rightfully assume that no data was sent which would be incorrect. Discussed at https://github.com/eventlet/eventlet/issues/260.
This commit is contained in:
@@ -351,28 +351,20 @@ class GreenSocket(object):
|
||||
if self.act_non_blocking:
|
||||
return fd.send(data, flags)
|
||||
|
||||
# blocking socket behavior - sends all, blocks if the buffer is full
|
||||
total_sent = 0
|
||||
len_data = len(data)
|
||||
while 1:
|
||||
try:
|
||||
total_sent += fd.send(data[total_sent:], flags)
|
||||
return fd.send(data, flags)
|
||||
except socket.error as e:
|
||||
eno = get_errno(e)
|
||||
if eno == errno.ENOTCONN or eno not in SOCKET_BLOCKING:
|
||||
raise
|
||||
|
||||
if total_sent == len_data:
|
||||
break
|
||||
|
||||
try:
|
||||
self._trampoline(self.fd, write=True, timeout=self.gettimeout(),
|
||||
timeout_exc=socket.timeout("timed out"))
|
||||
except IOClosed:
|
||||
raise socket.error(errno.ECONNRESET, 'Connection closed by another thread')
|
||||
|
||||
return total_sent
|
||||
|
||||
def sendall(self, data, flags=0):
|
||||
tail = self.send(data, flags)
|
||||
len_data = len(data)
|
||||
|
Reference in New Issue
Block a user