Geard: Handle connections closed while sending
If a connection is closed while sending a large amount of data, the send() call may return EAGAIN, even though the socket is in CLOSE_WAIT. In that case, just continue queuing the data, and let the main loop handle the disconnect (which it will detect via the poll call followed by a null read). Change-Id: Ib15eae81077b58d2f95fb0989ed1139c6d542f49
This commit is contained in:
parent
defb9722b8
commit
550873b76a
|
@ -2338,28 +2338,32 @@ class NonBlockingConnection(Connection):
|
|||
|
||||
def sendQueuedData(self):
|
||||
"""Send previously queued data to the socket."""
|
||||
while len(self.send_queue):
|
||||
data = self.send_queue.pop(0)
|
||||
r = 0
|
||||
try:
|
||||
r = self.conn.send(data)
|
||||
except ssl.SSLError as e:
|
||||
if e.errno == ssl.SSL_ERROR_WANT_READ:
|
||||
raise RetryIOError()
|
||||
elif e.errno == ssl.SSL_ERROR_WANT_WRITE:
|
||||
raise RetryIOError()
|
||||
else:
|
||||
raise
|
||||
except socket.error as e:
|
||||
if e.errno == errno.EAGAIN:
|
||||
self.log.debug("Write operation on %s would block"
|
||||
% self)
|
||||
else:
|
||||
raise
|
||||
finally:
|
||||
data = data[r:]
|
||||
if data:
|
||||
self.send_queue.insert(0, data)
|
||||
try:
|
||||
while len(self.send_queue):
|
||||
data = self.send_queue.pop(0)
|
||||
r = 0
|
||||
try:
|
||||
r = self.conn.send(data)
|
||||
except ssl.SSLError as e:
|
||||
if e.errno == ssl.SSL_ERROR_WANT_READ:
|
||||
raise RetryIOError()
|
||||
elif e.errno == ssl.SSL_ERROR_WANT_WRITE:
|
||||
raise RetryIOError()
|
||||
else:
|
||||
raise
|
||||
except socket.error as e:
|
||||
if e.errno == errno.EAGAIN:
|
||||
self.log.debug("Write operation on %s would block"
|
||||
% self)
|
||||
raise RetryIOError()
|
||||
else:
|
||||
raise
|
||||
finally:
|
||||
data = data[r:]
|
||||
if data:
|
||||
self.send_queue.insert(0, data)
|
||||
except RetryIOError:
|
||||
pass
|
||||
|
||||
|
||||
class ServerConnection(NonBlockingConnection):
|
||||
|
|
Loading…
Reference in New Issue