summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--paramiko/packet.py4
-rw-r--r--paramiko/transport.py13
2 files changed, 15 insertions, 2 deletions
diff --git a/paramiko/packet.py b/paramiko/packet.py
index 89a514d1..5dd4c49f 100644
--- a/paramiko/packet.py
+++ b/paramiko/packet.py
@@ -103,6 +103,10 @@ class Packetizer (object):
self.__handshake_complete = False
self.__timer_expired = False
+ @property
+ def closed(self):
+ return self.__closed
+
def set_log(self, log):
"""
Set the Python log object to use for logging.
diff --git a/paramiko/transport.py b/paramiko/transport.py
index 5e175230..64b96d4f 100644
--- a/paramiko/transport.py
+++ b/paramiko/transport.py
@@ -1532,8 +1532,17 @@ class Transport (threading.Thread, ClosingContextManager):
def stop_thread(self):
self.active = False
self.packetizer.close()
- while self.is_alive() and (self is not threading.current_thread()):
- self.join(10)
+ # Keep trying to join() our main thread, quickly, until:
+ # * We join()ed successfully (self.is_alive() == False)
+ # * Or it looks like we've hit issue #520 (socket.recv hitting some
+ # race condition preventing it from timing out correctly), wherein our
+ # socket and packetizer are both closed (but where we'd otherwise be
+ # sitting forever on that recv()).
+ while (
+ self.is_alive() and self is not threading.current_thread()
+ and not self.sock._closed and not self.packetizer.closed
+ ):
+ self.join(0.1)
### internals...