summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames E. Blair <jeblair@redhat.com>2016-07-15 14:56:42 -0700
committerJames E. Blair <jeblair@redhat.com>2016-07-15 14:56:42 -0700
commit550873b76abded12cd27c054b0dab0511ffd5e36 (patch)
tree38cc3cbf6420f3232211daa8fbba5c7803c5c3ba
parentdefb9722b8188981f15555ba04d5598da722e9c7 (diff)
downloadgear-550873b76abded12cd27c054b0dab0511ffd5e36.tar.gz
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
-rw-r--r--gear/__init__.py48
1 files changed, 26 insertions, 22 deletions
diff --git a/gear/__init__.py b/gear/__init__.py
index e03f3d0..d4d370f 100644
--- a/gear/__init__.py
+++ b/gear/__init__.py
@@ -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):