You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by gn...@apache.org on 2009/11/12 16:46:57 UTC

svn commit: r835419 - in /mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/common/channel: ChannelOutputStream.java Window.java

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;