[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.
This commit is contained in:
Robey Pointer 2003-12-24 22:09:43 +00:00
parent 02319afd5a
commit f6e1e84d60
1 changed files with 18 additions and 14 deletions

View File

@ -158,13 +158,14 @@ class Channel(object):
self.transport.send_message(m) self.transport.send_message(m)
def handle_eof(self, m): def handle_eof(self, m):
self.eof_received = 1
try: try:
self.lock.acquire() self.lock.acquire()
self.in_buffer_cv.notifyAll() if not self.eof_received:
if self.pipe_wfd != None: self.eof_received = 1
os.close(self.pipe_wfd) self.in_buffer_cv.notifyAll()
self.pipe_wfd = None if self.pipe_wfd != None:
os.close(self.pipe_wfd)
self.pipe_wfd = None
finally: finally:
self.lock.release() self.lock.release()
self.log(DEBUG, 'EOF received') self.log(DEBUG, 'EOF received')
@ -282,15 +283,18 @@ class Channel(object):
self.settimeout(0.0) self.settimeout(0.0)
def close(self): def close(self):
if self.closed or not self.active: try:
return self.lock.acquire()
self.send_eof() if self.active and not self.closed:
m = Message() self.send_eof()
m.add_byte(chr(MSG_CHANNEL_CLOSE)) m = Message()
m.add_int(self.remote_chanid) m.add_byte(chr(MSG_CHANNEL_CLOSE))
self.transport.send_message(m) m.add_int(self.remote_chanid)
self.closed = 1 self.transport.send_message(m)
self.transport.unlink_channel(self.chanid) self.closed = 1
self.transport.unlink_channel(self.chanid)
finally:
self.lock.release()
def recv_ready(self): def recv_ready(self):
"doesn't work if you've called fileno()" "doesn't work if you've called fileno()"