From ddb7d75c96806b0bac1fea3d8a17b8a9c982a18d Mon Sep 17 00:00:00 2001 From: Jeff Pinner Date: Fri, 18 May 2012 13:44:23 -0700 Subject: [PATCH] Make SslBufferPool an interface --- .../handler/ssl/DefaultSslBufferPool.java | 93 ++++++++++++++++ .../io/netty/handler/ssl/SslBufferPool.java | 105 ++---------------- .../java/io/netty/handler/ssl/SslHandler.java | 2 +- 3 files changed, 103 insertions(+), 97 deletions(-) create mode 100644 handler/src/main/java/io/netty/handler/ssl/DefaultSslBufferPool.java diff --git a/handler/src/main/java/io/netty/handler/ssl/DefaultSslBufferPool.java b/handler/src/main/java/io/netty/handler/ssl/DefaultSslBufferPool.java new file mode 100644 index 0000000000..6fe44d5894 --- /dev/null +++ b/handler/src/main/java/io/netty/handler/ssl/DefaultSslBufferPool.java @@ -0,0 +1,93 @@ +/* + * Copyright 2011 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package io.netty.handler.ssl; + +import java.nio.ByteBuffer; + +import javax.net.ssl.SSLEngine; + +public class DefaultSslBufferPool implements SslBufferPool { + + private static final int DEFAULT_POOL_SIZE = MAX_PACKET_SIZE * 1024; + + private final ByteBuffer[] pool; + private final int maxBufferCount; + private int index; + + /** + * Creates a new buffer pool whose size is {@code 18113536}, which can + * hold {@code 1024} buffers. + */ + public DefaultSslBufferPool() { + this(DEFAULT_POOL_SIZE); + } + + /** + * Creates a new buffer pool. + * + * @param maxPoolSize the maximum number of bytes that this pool can hold + */ + public DefaultSslBufferPool(int maxPoolSize) { + if (maxPoolSize <= 0) { + throw new IllegalArgumentException("maxPoolSize: " + maxPoolSize); + } + + int maxBufferCount = maxPoolSize / MAX_PACKET_SIZE; + if (maxPoolSize % MAX_PACKET_SIZE != 0) { + maxBufferCount ++; + } + + pool = new ByteBuffer[maxBufferCount]; + this.maxBufferCount = maxBufferCount; + } + + /** + * Returns the maximum size of this pool in byte unit. The returned value + * can be somewhat different from what was specified in the constructor. + */ + public int getMaxPoolSize() { + return maxBufferCount * MAX_PACKET_SIZE; + } + + /** + * Returns the number of bytes which were allocated but have not been + * acquired yet. You can estimate how optimal the specified maximum pool + * size is from this value. If it keeps returning {@code 0}, it means the + * pool is getting exhausted. If it keeps returns a unnecessarily big + * value, it means the pool is wasting the heap space. + */ + public synchronized int getUnacquiredPoolSize() { + return index * MAX_PACKET_SIZE; + } + + public ByteBuffer acquireBuffer() { + synchronized { + if (index == 0) { + return ByteBuffer.allocate(MAX_PACKET_SIZE); + } else { + return (ByteBuffer) pool[-- index].clear(); + } + } + } + + public void releaseBuffer(ByteBuffer buffer) { + synchronized { + if (index < maxBufferCount) { + pool[index ++] = buffer; + } + } + } +} diff --git a/handler/src/main/java/io/netty/handler/ssl/SslBufferPool.java b/handler/src/main/java/io/netty/handler/ssl/SslBufferPool.java index 164513a968..6cd3e18de1 100644 --- a/handler/src/main/java/io/netty/handler/ssl/SslBufferPool.java +++ b/handler/src/main/java/io/netty/handler/ssl/SslBufferPool.java @@ -17,15 +17,10 @@ package io.netty.handler.ssl; import java.nio.ByteBuffer; -import javax.net.ssl.SSLEngine; - /** * A {@link ByteBuffer} pool dedicated for {@link SslHandler} performance * improvement. - *

- * In most cases, you won't need to create a new pool instance because - * {@link SslHandler} has a default pool instance internally. - *

+ * * The reason why {@link SslHandler} requires a buffer pool is because the * current {@link SSLEngine} implementation always requires a 17KiB buffer for * every 'wrap' and 'unwrap' operation. In most cases, the actual size of the @@ -33,103 +28,21 @@ import javax.net.ssl.SSLEngine; * buffer for every 'wrap' and 'unwrap' operation wastes a lot of memory * bandwidth, resulting in the application performance degradation. */ -public class SslBufferPool { +public interface SslBufferPool { - // Add 1024 as a room for compressed data and another 1024 for Apache Harmony compatibility. - private static final int MAX_PACKET_SIZE = 16665 + 2048; - private static final int DEFAULT_POOL_SIZE = MAX_PACKET_SIZE * 1024; - - private final ByteBuffer[] pool; - private final int maxBufferCount; - private int index; - - /** - * Creates a new buffer pool whose size is {@code 18113536}, which can - * hold {@code 1024} buffers. - */ - public SslBufferPool() { - this(DEFAULT_POOL_SIZE); - } - - /** - * Creates a new buffer pool. - * - * @param maxPoolSize the maximum number of bytes that this pool can hold - */ - public SslBufferPool(int maxPoolSize) { - if (maxPoolSize <= 0) { - throw new IllegalArgumentException("maxPoolSize: " + maxPoolSize); - } - - int maxBufferCount = maxPoolSize / MAX_PACKET_SIZE; - if (maxPoolSize % MAX_PACKET_SIZE != 0) { - maxBufferCount ++; - } - - pool = new ByteBuffer[maxBufferCount]; - this.maxBufferCount = maxBufferCount; - } - - /** - * Returns the maximum size of this pool in byte unit. The returned value - * can be somewhat different from what was specified in the constructor. - */ - public int getMaxPoolSize() { - return maxBufferCount * MAX_PACKET_SIZE; - } - - /** - * Returns the number of bytes which were allocated but have not been - * acquired yet. You can estimate how optimal the specified maximum pool - * size is from this value. If it keeps returning {@code 0}, it means the - * pool is getting exhausted. If it keeps returns a unnecessarily big - * value, it means the pool is wasting the heap space. - */ - public synchronized int getUnacquiredPoolSize() { - return index * MAX_PACKET_SIZE; - } + // Returned buffers must be large enough to accomodate the maximum SSL record size. + // Header (5) + Data (2^14) + Compression (1024) + Encryption (1024) + MAC (20) + Padding (256) + int MAX_PACKET_SIZE = 18713; /** * Acquire a new {@link ByteBuffer} out of the {@link SslBufferPool} - * */ - public ByteBuffer acquireBuffer() { - return acquire(); - } - - /** - * Will get removed. Please use {@link #acquireBuffer()} - * - */ - @Deprecated - synchronized ByteBuffer acquire() { - if (index == 0) { - return ByteBuffer.allocate(MAX_PACKET_SIZE); - } else { - return (ByteBuffer) pool[-- index].clear(); - } - } - + ByteBuffer acquireBuffer(); /** - * Release a previous acquired {@link ByteBuffer} - * + * Release a previously acquired {@link ByteBuffer} + * * @param buffer */ - public void releaseBuffer(ByteBuffer buffer) { - release(buffer); - } - - /** - * Will get removed. Please use {@link #releaseBuffer(ByteBuffer)} - * - * @deprecated - * - */ - @Deprecated - synchronized void release(ByteBuffer buffer) { - if (index < maxBufferCount) { - pool[index ++] = buffer; - } - } + void releaseBuffer(ByteBuffer buffer); } diff --git a/handler/src/main/java/io/netty/handler/ssl/SslHandler.java b/handler/src/main/java/io/netty/handler/ssl/SslHandler.java index 3247d614a4..5a55075188 100644 --- a/handler/src/main/java/io/netty/handler/ssl/SslHandler.java +++ b/handler/src/main/java/io/netty/handler/ssl/SslHandler.java @@ -170,7 +170,7 @@ public class SslHandler extends FrameDecoder */ public static synchronized SslBufferPool getDefaultBufferPool() { if (defaultBufferPool == null) { - defaultBufferPool = new SslBufferPool(); + defaultBufferPool = new DefaultSslBufferPool(); } return defaultBufferPool; }