Author: gnodet Date: Thu Nov 12 15:46:57 2009 New Revision: 835419 URL: http://svn.apache.org/viewvc?rev=835419&view=rev Log: SSHD-49: Fix a problem with the Output channel logic for the remote window
Modified: mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/common/channel/ChannelOutputStream.java mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/common/channel/Window.java Modified: mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/common/channel/ChannelOutputStream.java URL: http://svn.apache.org/viewvc/mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/common/channel/ChannelOutputStream.java?rev=835419&r1=835418&r2=835419&view=diff ============================================================================== --- mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/common/channel/ChannelOutputStream.java (original) +++ mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/common/channel/ChannelOutputStream.java Thu Nov 12 15:46:57 2009 @@ -77,18 +77,24 @@ if (closed) { throw new SshException("Already closed"); } - int pos = buffer.wpos(); - if (bufferLength <= 0) { - // No data to send - return; - } - buffer.wpos(cmd == SshConstants.Message.SSH_MSG_CHANNEL_EXTENDED_DATA ? 14 : 10); - buffer.putInt(bufferLength); - buffer.wpos(pos); try { - remoteWindow.waitAndConsume(bufferLength); - log.debug("Send {} on channel {}", cmd, channel.getId()); - channel.getSession().writePacket(buffer); + while (bufferLength > 0) { + Buffer buf = buffer; + int total = bufferLength; + int length = Math.min(remoteWindow.waitForSpace(), total); + int pos = buf.wpos(); + buf.wpos(cmd == SshConstants.Message.SSH_MSG_CHANNEL_EXTENDED_DATA ? 14 : 10); + buf.putInt(length); + buf.wpos(pos); + newBuffer(); + if (total > length) { + buffer.putBytes(buf.array(), pos - (total - length), total - length); + bufferLength = total - length; + } + remoteWindow.waitAndConsume(length); + log.debug("Send {} on channel {}", cmd, channel.getId()); + channel.getSession().writePacket(buf); + } } catch (WindowClosedException e) { closed = true; throw e; Modified: mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/common/channel/Window.java URL: http://svn.apache.org/viewvc/mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/common/channel/Window.java?rev=835419&r1=835418&r2=835419&view=diff ============================================================================== --- mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/common/channel/Window.java (original) +++ mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/common/channel/Window.java Thu Nov 12 15:46:57 2009 @@ -54,7 +54,9 @@ } public int getSize() { - return size; + synchronized (lock) { + return size; + } } public int getMaxSize() { @@ -137,6 +139,24 @@ } } + public int waitForSpace() throws InterruptedException, WindowClosedException { + synchronized (lock) { + while (size == 0 && !closed) { + log.debug("Waiting for some space on {}", name); + waiting = true; + lock.wait(); + } + if (waiting) { + log.debug("Space available for {}", name); + waiting = false; + } + if (closed) { + throw new WindowClosedException(); + } + return size; + } + } + public void notifyClosed() { synchronized (lock) { closed = true;