summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRobey Pointer <robey@lag.net>2004-05-17 07:41:50 +0000
committerRobey Pointer <robey@lag.net>2004-05-17 07:41:50 +0000
commited77581d7a8a36af5a141d8bac41213aa9ef750a (patch)
tree21603ec0945c5d8996b4d30e59bd2901b900ac4e
parent36a867a01767485106e91d8046314bd8f45331f8 (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.py17
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!