diff options
author | Robey Pointer <robey@lag.net> | 2003-12-24 22:09:43 +0000 |
---|---|---|
committer | Robey Pointer <robey@lag.net> | 2003-12-24 22:09:43 +0000 |
commit | f6e1e84d60ae75cd28030b4c41856ec768566a46 (patch) | |
tree | 2626b39833a8a4306b43546aad52d4e748f014c7 /channel.py | |
parent | 02319afd5ac24ebeed0d4f671179128c4fc39596 (diff) |
[project @ Arch-1:robey@lag.net--2003-public%secsh--dev--1.0--patch-13]
fix a deadlock/race in handle_eof & close
(patch from fred gansevles)
add locking around the eof handler and the close() call, so we can't be in
both simultaneously.
Diffstat (limited to 'channel.py')
-rw-r--r-- | channel.py | 32 |
1 files changed, 18 insertions, 14 deletions
@@ -158,13 +158,14 @@ class Channel(object): self.transport.send_message(m) def handle_eof(self, m): - self.eof_received = 1 try: self.lock.acquire() - self.in_buffer_cv.notifyAll() - if self.pipe_wfd != None: - os.close(self.pipe_wfd) - self.pipe_wfd = None + if not self.eof_received: + self.eof_received = 1 + self.in_buffer_cv.notifyAll() + if self.pipe_wfd != None: + os.close(self.pipe_wfd) + self.pipe_wfd = None finally: self.lock.release() self.log(DEBUG, 'EOF received') @@ -282,15 +283,18 @@ class Channel(object): self.settimeout(0.0) def close(self): - if self.closed or not self.active: - return - self.send_eof() - m = Message() - m.add_byte(chr(MSG_CHANNEL_CLOSE)) - m.add_int(self.remote_chanid) - self.transport.send_message(m) - self.closed = 1 - self.transport.unlink_channel(self.chanid) + try: + self.lock.acquire() + if self.active and not self.closed: + self.send_eof() + m = Message() + m.add_byte(chr(MSG_CHANNEL_CLOSE)) + m.add_int(self.remote_chanid) + self.transport.send_message(m) + self.closed = 1 + self.transport.unlink_channel(self.chanid) + finally: + self.lock.release() def recv_ready(self): "doesn't work if you've called fileno()" |