summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRobey Pointer <robey@lag.net>2004-03-08 09:47:47 +0000
committerRobey Pointer <robey@lag.net>2004-03-08 09:47:47 +0000
commitc565d66e390f613f776146665bebbe63a163b0e2 (patch)
treed4af8a3851e88cab7a1b42eae2ecdb0196f4dd5b
parent3e31771637cb87e2cae2092121562b47ea13cd6e (diff)
[project @ Arch-1:robey@lag.net--2003-public%secsh--dev--1.0--patch-28]
fix lingering thread bug this bug has been in there forever and i could never figure out a workaround till now. when the python interpreter exits, it doesn't necessarily destroy the remaining objects or call __del__ on anything, and it will lock up until all threads finish running. how the threads are supposed to notice the exiting interpreter has always been sort of a mystery to me. tonight i figured out how to use the 'atexit' module to register a handler that runs when the interpreter exits. now we keep a list of active threads and ask them all to exit on shutdown. no more going to another shell to kill -9 python! yeah!!
-rw-r--r--paramiko/transport.py11
1 files changed, 11 insertions, 0 deletions
diff --git a/paramiko/transport.py b/paramiko/transport.py
index 69669aaa..ea623229 100644
--- a/paramiko/transport.py
+++ b/paramiko/transport.py
@@ -76,6 +76,15 @@ except:
randpool.randomize()
+# for thread cleanup
+_active_threads = []
+def _join_lingering_threads():
+ for thr in _active_threads:
+ thr.active = False
+import atexit
+atexit.register(_join_lingering_threads)
+
+
class BaseTransport (threading.Thread):
"""
Handles protocol negotiation, key exchange, encryption, and the creation
@@ -788,6 +797,7 @@ class BaseTransport (threading.Thread):
def _run(self):
self.active = True
+ _active_threads.append(self)
try:
# SSH-1.99-OpenSSH_2.9p2
self._write_all(self.local_version + '\r\n')
@@ -838,6 +848,7 @@ class BaseTransport (threading.Thread):
self._log(DEBUG, 'Unknown exception: ' + str(e))
self._log(DEBUG, tb_strings())
self.saved_exception = e
+ _active_threads.remove(self)
if self.active:
self.active = False
if self.completion_event != None: