diff options
author | Robey Pointer <robey@lag.net> | 2005-02-28 07:16:22 +0000 |
---|---|---|
committer | Robey Pointer <robey@lag.net> | 2005-02-28 07:16:22 +0000 |
commit | 246f3d46a291cc186128ac84a8916f53d4e9effb (patch) | |
tree | 18b55923d919c18fc8b31a4ae0879d5a805b6288 | |
parent | 4b8a9d3b7af4f80d3c4fc0d541c5425a063471a6 (diff) |
[project @ Arch-1:robey@lag.net--2003-public%secsh--dev--1.0--patch-151]
fix race in transport thread startup
set active=True from the methods that start the main transport thread, right
before actually starting the thread. this avoids a race where the main
thread could be started, but the original thread could wake up from the
event.wait(0.1) before the new thread actually set the transport active.
impossible, you say? no machines so slow exist? au contraire, my sad
little linux box faced this problem earlier today.
-rw-r--r-- | paramiko/transport.py | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/paramiko/transport.py b/paramiko/transport.py index 97026e80..541b29d8 100644 --- a/paramiko/transport.py +++ b/paramiko/transport.py @@ -269,7 +269,7 @@ class BaseTransport (threading.Thread): @rtype: str """ - out = '<paramiko.BaseTransport at %s' % hex(id(self)) + out = '<paramiko.BaseTransport at %s' % hex(long(id(self)) & 0xffffffffL) if not self.active: out += ' (unconnected)' else: @@ -320,6 +320,7 @@ class BaseTransport (threading.Thread): @type event: threading.Event """ self.completion_event = event + self.active = True self.start() def start_server(self, event=None, server=None): @@ -360,6 +361,7 @@ class BaseTransport (threading.Thread): self.server_mode = True self.server_object = server self.completion_event = event + self.active = True self.start() def add_server_key(self, key): @@ -708,7 +710,7 @@ class BaseTransport (threading.Thread): event = threading.Event() self.start_client(event) - while 1: + while True: event.wait(0.1) if not self.active: e = self.get_exception() @@ -887,7 +889,7 @@ class BaseTransport (threading.Thread): while len(out) > 0: try: n = self.sock.send(out) - except: + except Exception, x: # could be: (32, 'Broken pipe') n = -1 if n < 0: @@ -1062,10 +1064,13 @@ class BaseTransport (threading.Thread): return self._cipher_info[name]['class'].new(key, self._cipher_info[name]['mode'], iv) def _run(self): - self.active = True + # active=True occurs before the thread is launched, to avoid a race _active_threads.append(self) + if self.server_mode: + self._log(DEBUG, 'starting thread (server mode): %s' % hex(long(id(self)) & 0xffffffffL)) + else: + self._log(DEBUG, 'starting thread (client mode): %s' % hex(long(id(self)) & 0xffffffffL)) try: - # SSH-1.99-OpenSSH_2.9p2 self._write_all(self.local_version + '\r\n') self._check_banner() self._send_kex_init() |