diff options
author | Robey Pointer <robey@lag.net> | 2004-05-17 07:41:50 +0000 |
---|---|---|
committer | Robey Pointer <robey@lag.net> | 2004-05-17 07:41:50 +0000 |
commit | ed77581d7a8a36af5a141d8bac41213aa9ef750a (patch) | |
tree | 21603ec0945c5d8996b4d30e59bd2901b900ac4e | |
parent | 36a867a01767485106e91d8046314bd8f45331f8 (diff) |
[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.
-rw-r--r-- | paramiko/channel.py | 17 |
1 files changed, 9 insertions, 8 deletions
diff --git a/paramiko/channel.py b/paramiko/channel.py index b339f315..2f5968d7 100644 --- a/paramiko/channel.py +++ b/paramiko/channel.py @@ -724,13 +724,10 @@ class Channel (object): self.logger.log(level, msg) def _set_closed(self): + # you are holding the lock. self.closed = True - try: - self.lock.acquire() - self.in_buffer_cv.notifyAll() - self.out_buffer_cv.notifyAll() - finally: - self.lock.release() + self.in_buffer_cv.notifyAll() + self.out_buffer_cv.notifyAll() def _send_eof(self): if self.eof_sent: @@ -824,8 +821,12 @@ class Channel (object): def _unlink(self): if self.closed or not self.active: return - self._set_closed() - self.transport._unlink_channel(self.chanid) + try: + self.lock.acquire() + self._set_closed() + self.transport._unlink_channel(self.chanid) + finally: + self.lock.release() def _check_add_window(self, n): # already holding the lock! |