diff options
author | James E. Blair <jeblair@redhat.com> | 2016-07-15 14:56:42 -0700 |
---|---|---|
committer | James E. Blair <jeblair@redhat.com> | 2016-07-15 14:56:42 -0700 |
commit | 550873b76abded12cd27c054b0dab0511ffd5e36 (patch) | |
tree | 38cc3cbf6420f3232211daa8fbba5c7803c5c3ba /gear | |
parent | defb9722b8188981f15555ba04d5598da722e9c7 (diff) | |
download | gear-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
Diffstat (limited to 'gear')
-rw-r--r-- | gear/__init__.py | 48 |
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): |