summaryrefslogtreecommitdiffhomepage
path: root/channel.py
diff options
context:
space:
mode:
authorRobey Pointer <robey@lag.net>2003-12-24 22:09:43 +0000
committerRobey Pointer <robey@lag.net>2003-12-24 22:09:43 +0000
commitf6e1e84d60ae75cd28030b4c41856ec768566a46 (patch)
tree2626b39833a8a4306b43546aad52d4e748f014c7 /channel.py
parent02319afd5ac24ebeed0d4f671179128c4fc39596 (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.py32
1 files changed, 18 insertions, 14 deletions
diff --git a/channel.py b/channel.py
index de1e31e5..fa0ff7c8 100644
--- a/channel.py
+++ b/channel.py
@@ -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()"