diff options
author | Robey Pointer <robey@lag.net> | 2005-10-29 20:41:14 +0000 |
---|---|---|
committer | Robey Pointer <robey@lag.net> | 2005-10-29 20:41:14 +0000 |
commit | 3c67e35b5f6fbc686141c31d513195705fff14d7 (patch) | |
tree | c92625f948129e0bcc14576f91fa9bc269b90dae | |
parent | f65edffbfb2378246d7bfb6e7256a2854e3963e4 (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.py | 29 |
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): """ |