[project @ Arch-1:robey@lag.net--2003-public%secsh--dev--1.0--patch-52]

fix deadlock in closing a channel
closing a channel would enter an odd codepath where the lock was grabbed,
some stuff was done, then another function was called where the lock was
grabbed again.  unfortunately python locks aren't monitors so this would
deadlock.  instead, make the smaller function lock-free with an explicit
notice that you must be holding the lock before calling.
This commit is contained in:
Robey Pointer 2004-05-17 07:41:50 +00:00
parent 36a867a017
commit ed77581d7a
1 changed files with 9 additions and 8 deletions

View File

@ -724,13 +724,10 @@ class Channel (object):
self.logger.log(level, msg) self.logger.log(level, msg)
def _set_closed(self): def _set_closed(self):
# you are holding the lock.
self.closed = True self.closed = True
try: self.in_buffer_cv.notifyAll()
self.lock.acquire() self.out_buffer_cv.notifyAll()
self.in_buffer_cv.notifyAll()
self.out_buffer_cv.notifyAll()
finally:
self.lock.release()
def _send_eof(self): def _send_eof(self):
if self.eof_sent: if self.eof_sent:
@ -824,8 +821,12 @@ class Channel (object):
def _unlink(self): def _unlink(self):
if self.closed or not self.active: if self.closed or not self.active:
return return
self._set_closed() try:
self.transport._unlink_channel(self.chanid) self.lock.acquire()
self._set_closed()
self.transport._unlink_channel(self.chanid)
finally:
self.lock.release()
def _check_add_window(self, n): def _check_add_window(self, n):
# already holding the lock! # already holding the lock!