[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:
parent
36a867a017
commit
ed77581d7a
|
@ -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!
|
||||||
|
|
Loading…
Reference in New Issue