summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRobey Pointer <robey@lag.net>2005-10-29 20:41:14 +0000
committerRobey Pointer <robey@lag.net>2005-10-29 20:41:14 +0000
commit3c67e35b5f6fbc686141c31d513195705fff14d7 (patch)
treec92625f948129e0bcc14576f91fa9bc269b90dae
parentf65edffbfb2378246d7bfb6e7256a2854e3963e4 (diff)
[project @ Arch-1:robey@lag.net--2005-master-shake%paramiko--dev--1--patch-71]
the window-adjust can be sent outside of the lock, as long as the window size tracking is done within the lock (ie: allocate window space within the lock, then send the ack later) -- helps avoid deadlocks
-rw-r--r--paramiko/channel.py29
1 files changed, 18 insertions, 11 deletions
diff --git a/paramiko/channel.py b/paramiko/channel.py
index 5edf4b3e..97c7df5f 100644
--- a/paramiko/channel.py
+++ b/paramiko/channel.py
@@ -539,9 +539,18 @@ class Channel (object):
else:
out = self.in_buffer[:nbytes]
self.in_buffer = self.in_buffer[nbytes:]
- self._check_add_window(len(out))
+ ack = self._check_add_window(len(out))
finally:
self.lock.release()
+
+ # no need to hold the channel lock when sending this
+ if ack > 0:
+ m = Message()
+ m.add_byte(chr(MSG_CHANNEL_WINDOW_ADJUST))
+ m.add_int(self.remote_chanid)
+ m.add_int(ack)
+ self.transport._send_user_message(m)
+
return out
def recv_stderr_ready(self):
@@ -1056,19 +1065,17 @@ class Channel (object):
def _check_add_window(self, n):
# already holding the lock!
if self.closed or self.eof_received or not self.active:
- return
+ return 0
if self.ultra_debug:
self._log(DEBUG, 'addwindow %d' % n)
self.in_window_sofar += n
- if self.in_window_sofar > self.in_window_threshold:
- if self.ultra_debug:
- self._log(DEBUG, 'addwindow send %d' % self.in_window_sofar)
- m = Message()
- m.add_byte(chr(MSG_CHANNEL_WINDOW_ADJUST))
- m.add_int(self.remote_chanid)
- m.add_int(self.in_window_sofar)
- self.transport._send_user_message(m)
- self.in_window_sofar = 0
+ if self.in_window_sofar <= self.in_window_threshold:
+ return 0
+ if self.ultra_debug:
+ self._log(DEBUG, 'addwindow send %d' % self.in_window_sofar)
+ out = self.in_window_sofar
+ self.in_window_sofar = 0
+ return out
def _wait_for_send_window(self, size):
"""