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 2015/03/30 10:24:59 UTC

[3/3] mina-sshd git commit: [SSHD-439] Re-use read buffer in Nio2Session

[SSHD-439] Re-use read buffer in Nio2Session

Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/eb4fc83d
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/eb4fc83d
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/eb4fc83d

Branch: refs/heads/master
Commit: eb4fc83d6e4c5c881bde90d01a50ca9103f98951
Parents: 6824d75
Author: Guillaume Nodet <gn...@apache.org>
Authored: Mon Mar 30 10:19:19 2015 +0200
Committer: Guillaume Nodet <gn...@apache.org>
Committed: Mon Mar 30 10:24:40 2015 +0200

----------------------------------------------------------------------
 .../org/apache/sshd/common/FactoryManager.java  |  6 ++
 .../sshd/common/io/nio2/Nio2Acceptor.java       |  2 +-
 .../sshd/common/io/nio2/Nio2Connector.java      |  2 +-
 .../apache/sshd/common/io/nio2/Nio2Session.java | 65 +++++++++++++++-----
 4 files changed, 57 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/eb4fc83d/sshd-core/src/main/java/org/apache/sshd/common/FactoryManager.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/FactoryManager.java b/sshd-core/src/main/java/org/apache/sshd/common/FactoryManager.java
index 14fd6d6..123140f 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/FactoryManager.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/FactoryManager.java
@@ -128,6 +128,12 @@ public interface FactoryManager {
     public static final String TCP_NODELAY = "tcp-nodelay";
 
     /**
+     * Read buffer size for NIO2 sessions
+     * See {@link org.apache.sshd.common.io.nio2.Nio2Session}
+     */
+    public static final String NIO2_READ_BUFFER_SIZE = "nio2-read-buf-size";
+
+    /**
      * A map of properties that can be used to configure the SSH server
      * or client.  This map will never be changed by either the server or
      * client and is not supposed to be changed at runtime (changes are not

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/eb4fc83d/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Acceptor.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Acceptor.java b/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Acceptor.java
index 5d1a0ae..5593ea5 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Acceptor.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Acceptor.java
@@ -127,7 +127,7 @@ public class Nio2Acceptor extends Nio2Service implements IoAcceptor {
             }
             try {
                 // Create a session
-                Nio2Session session = new Nio2Session(Nio2Acceptor.this, handler, result);
+                Nio2Session session = new Nio2Session(Nio2Acceptor.this, manager, handler, result);
                 handler.sessionCreated(session);
                 sessions.put(session.getId(), session);
                 session.startReading();

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/eb4fc83d/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Connector.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Connector.java b/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Connector.java
index 0ad182b..1318280 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Connector.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Connector.java
@@ -53,7 +53,7 @@ public class Nio2Connector extends Nio2Service implements IoConnector {
             socket.connect(address, null, new Nio2CompletionHandler<Void, Object>() {
                 protected void onCompleted(Void result, Object attachment) {
                     try {
-                        Nio2Session session = new Nio2Session(Nio2Connector.this, handler, socket);
+                        Nio2Session session = new Nio2Session(Nio2Connector.this, manager, handler, socket);
                         handler.sessionCreated(session);
                         sessions.put(session.getId(), session);
                         future.setSession(session);

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/eb4fc83d/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Session.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Session.java b/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Session.java
index 8fb1f3c..9822c2d 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Session.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Session.java
@@ -30,6 +30,8 @@ import java.util.concurrent.LinkedTransferQueue;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.concurrent.atomic.AtomicReference;
 
+import org.apache.sshd.common.FactoryManager;
+import org.apache.sshd.common.FactoryManagerUtils;
 import org.apache.sshd.common.SshException;
 import org.apache.sshd.common.future.CloseFuture;
 import org.apache.sshd.common.future.DefaultSshFuture;
@@ -45,7 +47,9 @@ import org.apache.sshd.common.util.Readable;
  */
 public class Nio2Session extends CloseableUtils.AbstractCloseable implements IoSession {
 
-    private static final AtomicLong sessionIdGenerator = new AtomicLong(100);
+    public static final int DEFAULT_READBUF_SIZE = 32 * 1024;
+
+    private static final AtomicLong sessionIdGenerator = new AtomicLong(100L);
 
     private final long id = sessionIdGenerator.incrementAndGet();
     private final Nio2Service service;
@@ -54,12 +58,13 @@ public class Nio2Session extends CloseableUtils.AbstractCloseable implements IoS
     private final Map<Object, Object> attributes = new HashMap<Object, Object>();
     private final SocketAddress localAddress;
     private final SocketAddress remoteAddress;
-
+    private final FactoryManager manager;
     private final Queue<DefaultIoWriteFuture> writes = new LinkedTransferQueue<DefaultIoWriteFuture>();
     private final AtomicReference<DefaultIoWriteFuture> currentWrite = new AtomicReference<DefaultIoWriteFuture>();
 
-    public Nio2Session(Nio2Service service, IoHandler handler, AsynchronousSocketChannel socket) throws IOException {
+    public Nio2Session(Nio2Service service, FactoryManager manager, IoHandler handler, AsynchronousSocketChannel socket) throws IOException {
         this.service = service;
+        this.manager = manager;
         this.handler = handler;
         this.socket = socket;
         this.localAddress = socket.getLocalAddress();
@@ -166,24 +171,45 @@ public class Nio2Session extends CloseableUtils.AbstractCloseable implements IoS
     }
 
     public void startReading() {
-        final ByteBuffer buffer = ByteBuffer.allocate(32 * 1024);
-        socket.read(buffer, null, new Nio2CompletionHandler<Integer, Object>() {
+        startReading(FactoryManagerUtils.getIntProperty(manager, FactoryManager.NIO2_READ_BUFFER_SIZE, DEFAULT_READBUF_SIZE));
+    }
+
+    public void startReading(int bufSize) {
+        startReading(new byte[bufSize]);
+    }
+
+    public void startReading(byte[] buf) {
+        startReading(buf, 0, buf.length);
+    }
+    
+    public void startReading(byte[] buf, int offset, int len) {
+        startReading(ByteBuffer.wrap(buf, offset, len));
+    }
+
+    public void startReading(final ByteBuffer buffer) {
+        doReadCycle(buffer, new Readable() {
+                public int available() {
+                    return buffer.remaining();
+                }
+                public void getRawBytes(byte[] data, int offset, int len) {
+                    buffer.get(data, offset, len);
+                }
+            });
+    }
+
+    protected void doReadCycle(final ByteBuffer buffer, final Readable bufReader) {
+        final Nio2CompletionHandler<Integer, Object> completion = new Nio2CompletionHandler<Integer, Object>() {
+            @SuppressWarnings("synthetic-access")
             protected void onCompleted(Integer result, Object attachment) {
                 try {
                     if (result >= 0) {
                         log.debug("Read {} bytes", result);
                         buffer.flip();
-                        Readable buf = new Readable() {
-                            public int available() {
-                                return buffer.remaining();
-                            }
-                            public void getRawBytes(byte[] data, int offset, int len) {
-                                buffer.get(data, offset, len);
-                            }
-                        };
-                        handler.messageReceived(Nio2Session.this, buf);
+                        handler.messageReceived(Nio2Session.this, bufReader);
                         if (!closeFuture.isClosed()) {
-                            startReading();
+                            // re-use reference for next iteration since we finished processing it
+                            buffer.clear();
+                            doReadCycle(buffer, this);
                         } else {
                             log.debug("IoSession has been closed, stop reading");
                         }
@@ -195,10 +221,17 @@ public class Nio2Session extends CloseableUtils.AbstractCloseable implements IoS
                     failed(exc, attachment);
                 }
             }
+
+            @SuppressWarnings("synthetic-access")
             protected void onFailed(Throwable exc, Object attachment) {
                 exceptionCaught(exc);
             }
-        });
+        };
+        doReadCycle(buffer, completion);
+    }
+
+    protected void doReadCycle(ByteBuffer buffer, Nio2CompletionHandler<Integer, Object> completion) {
+        socket.read(buffer, null, completion);
     }
 
     private void startWriting() {