[project @ Arch-1:robey@lag.net--2003-public%secsh--dev--1.0--patch-98]
don't unlink a Channel until the server closes it too when close()'ing a Channel, don't immediately unlink it from the Transport. instead, wait for the server to send a close message. this should fix a bug where doing close() on an EOF'd channel would cause the entire transport to be killed, because the server would send an 'exit-status' and 'close' message for a channel that we no longer had a record of.
This commit is contained in:
parent
d7caa20213
commit
6eb59a2b53
|
@ -359,19 +359,21 @@ class Channel (object):
|
||||||
is flushed). Channels are automatically closed when they are garbage-
|
is flushed). Channels are automatically closed when they are garbage-
|
||||||
collected, or when their L{Transport} is closed.
|
collected, or when their L{Transport} is closed.
|
||||||
"""
|
"""
|
||||||
|
self.lock.acquire()
|
||||||
try:
|
try:
|
||||||
self.lock.acquire()
|
if not self.active or self.closed:
|
||||||
if self.active and not self.closed:
|
return
|
||||||
try:
|
try:
|
||||||
self._send_eof()
|
self._send_eof()
|
||||||
m = Message()
|
m = Message()
|
||||||
m.add_byte(chr(MSG_CHANNEL_CLOSE))
|
m.add_byte(chr(MSG_CHANNEL_CLOSE))
|
||||||
m.add_int(self.remote_chanid)
|
m.add_int(self.remote_chanid)
|
||||||
self.transport._send_user_message(m)
|
self.transport._send_user_message(m)
|
||||||
except EOFError:
|
except EOFError:
|
||||||
pass
|
pass
|
||||||
self._set_closed()
|
self._set_closed()
|
||||||
self.transport._unlink_channel(self.chanid)
|
# can't unlink from the Transport yet -- the remote side may still
|
||||||
|
# try to send meta-data (exit-status, etc)
|
||||||
finally:
|
finally:
|
||||||
self.lock.release()
|
self.lock.release()
|
||||||
|
|
||||||
|
@ -722,10 +724,9 @@ class Channel (object):
|
||||||
|
|
||||||
def _handle_close(self, m):
|
def _handle_close(self, m):
|
||||||
self.close()
|
self.close()
|
||||||
|
self.lock.acquire()
|
||||||
try:
|
try:
|
||||||
self.lock.acquire()
|
self.transport._unlink_channel(self.chanid)
|
||||||
self.in_buffer_cv.notifyAll()
|
|
||||||
self.out_buffer_cv.notifyAll()
|
|
||||||
if self.pipe_wfd != None:
|
if self.pipe_wfd != None:
|
||||||
os.close(self.pipe_wfd)
|
os.close(self.pipe_wfd)
|
||||||
self.pipe_wfd = None
|
self.pipe_wfd = None
|
||||||
|
|
Loading…
Reference in New Issue