diff options
author | Robey Pointer <robey@lag.net> | 2004-03-08 09:47:47 +0000 |
---|---|---|
committer | Robey Pointer <robey@lag.net> | 2004-03-08 09:47:47 +0000 |
commit | c565d66e390f613f776146665bebbe63a163b0e2 (patch) | |
tree | d4af8a3851e88cab7a1b42eae2ecdb0196f4dd5b | |
parent | 3e31771637cb87e2cae2092121562b47ea13cd6e (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.py | 11 |
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: |