[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.
This commit is contained in:
parent
4b8a9d3b7a
commit
246f3d46a2
|
@ -269,7 +269,7 @@ class BaseTransport (threading.Thread):
|
||||||
|
|
||||||
@rtype: str
|
@rtype: str
|
||||||
"""
|
"""
|
||||||
out = '<paramiko.BaseTransport at %s' % hex(id(self))
|
out = '<paramiko.BaseTransport at %s' % hex(long(id(self)) & 0xffffffffL)
|
||||||
if not self.active:
|
if not self.active:
|
||||||
out += ' (unconnected)'
|
out += ' (unconnected)'
|
||||||
else:
|
else:
|
||||||
|
@ -320,6 +320,7 @@ class BaseTransport (threading.Thread):
|
||||||
@type event: threading.Event
|
@type event: threading.Event
|
||||||
"""
|
"""
|
||||||
self.completion_event = event
|
self.completion_event = event
|
||||||
|
self.active = True
|
||||||
self.start()
|
self.start()
|
||||||
|
|
||||||
def start_server(self, event=None, server=None):
|
def start_server(self, event=None, server=None):
|
||||||
|
@ -360,6 +361,7 @@ class BaseTransport (threading.Thread):
|
||||||
self.server_mode = True
|
self.server_mode = True
|
||||||
self.server_object = server
|
self.server_object = server
|
||||||
self.completion_event = event
|
self.completion_event = event
|
||||||
|
self.active = True
|
||||||
self.start()
|
self.start()
|
||||||
|
|
||||||
def add_server_key(self, key):
|
def add_server_key(self, key):
|
||||||
|
@ -708,7 +710,7 @@ class BaseTransport (threading.Thread):
|
||||||
|
|
||||||
event = threading.Event()
|
event = threading.Event()
|
||||||
self.start_client(event)
|
self.start_client(event)
|
||||||
while 1:
|
while True:
|
||||||
event.wait(0.1)
|
event.wait(0.1)
|
||||||
if not self.active:
|
if not self.active:
|
||||||
e = self.get_exception()
|
e = self.get_exception()
|
||||||
|
@ -887,7 +889,7 @@ class BaseTransport (threading.Thread):
|
||||||
while len(out) > 0:
|
while len(out) > 0:
|
||||||
try:
|
try:
|
||||||
n = self.sock.send(out)
|
n = self.sock.send(out)
|
||||||
except:
|
except Exception, x:
|
||||||
# could be: (32, 'Broken pipe')
|
# could be: (32, 'Broken pipe')
|
||||||
n = -1
|
n = -1
|
||||||
if n < 0:
|
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)
|
return self._cipher_info[name]['class'].new(key, self._cipher_info[name]['mode'], iv)
|
||||||
|
|
||||||
def _run(self):
|
def _run(self):
|
||||||
self.active = True
|
# active=True occurs before the thread is launched, to avoid a race
|
||||||
_active_threads.append(self)
|
_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:
|
try:
|
||||||
# SSH-1.99-OpenSSH_2.9p2
|
|
||||||
self._write_all(self.local_version + '\r\n')
|
self._write_all(self.local_version + '\r\n')
|
||||||
self._check_banner()
|
self._check_banner()
|
||||||
self._send_kex_init()
|
self._send_kex_init()
|
||||||
|
|
Loading…
Reference in New Issue