diff options
author | Robey Pointer <robey@lag.net> | 2004-11-01 03:54:01 +0000 |
---|---|---|
committer | Robey Pointer <robey@lag.net> | 2004-11-01 03:54:01 +0000 |
commit | 6eb59a2b533fa61566ff01865a784b6c720db51b (patch) | |
tree | 3ab688fd35c7d74dc74ad9232b0e4ffb626872a4 | |
parent | d7caa20213130445f5631e7b0aebfc5fb1507ec6 (diff) |
[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.
-rw-r--r-- | paramiko/channel.py | 31 |
1 files changed, 16 insertions, 15 deletions
diff --git a/paramiko/channel.py b/paramiko/channel.py index cb22a6b2..9b7384e3 100644 --- a/paramiko/channel.py +++ b/paramiko/channel.py @@ -359,19 +359,21 @@ class Channel (object): is flushed). Channels are automatically closed when they are garbage- collected, or when their L{Transport} is closed. """ + self.lock.acquire() try: - self.lock.acquire() - if self.active and not self.closed: - try: - self._send_eof() - m = Message() - m.add_byte(chr(MSG_CHANNEL_CLOSE)) - m.add_int(self.remote_chanid) - self.transport._send_user_message(m) - except EOFError: - pass - self._set_closed() - self.transport._unlink_channel(self.chanid) + if not self.active or self.closed: + return + try: + self._send_eof() + m = Message() + m.add_byte(chr(MSG_CHANNEL_CLOSE)) + m.add_int(self.remote_chanid) + self.transport._send_user_message(m) + except EOFError: + pass + self._set_closed() + # can't unlink from the Transport yet -- the remote side may still + # try to send meta-data (exit-status, etc) finally: self.lock.release() @@ -722,10 +724,9 @@ class Channel (object): def _handle_close(self, m): self.close() + self.lock.acquire() try: - self.lock.acquire() - self.in_buffer_cv.notifyAll() - self.out_buffer_cv.notifyAll() + self.transport._unlink_channel(self.chanid) if self.pipe_wfd != None: os.close(self.pipe_wfd) self.pipe_wfd = None |