From f89907dba54bcd8d6d5d2c8f9badbec24b7e4ee0 Mon Sep 17 00:00:00 2001 From: Norman Maurer Date: Wed, 13 Aug 2014 16:40:34 +0200 Subject: [PATCH] Revert "[#2762] Not expand ByteBuffer[] in ChannelOutboundBuffer" This reverts commit de3c0507c12f9e03f11589f922020cf1320c042f as it may cause problem if a CompositeByteBuf has more then 1024 components. --- .../netty/channel/ChannelOutboundBuffer.java | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/transport/src/main/java/io/netty/channel/ChannelOutboundBuffer.java b/transport/src/main/java/io/netty/channel/ChannelOutboundBuffer.java index 4fb43fd53f..b74e1793f3 100644 --- a/transport/src/main/java/io/netty/channel/ChannelOutboundBuffer.java +++ b/transport/src/main/java/io/netty/channel/ChannelOutboundBuffer.java @@ -46,10 +46,6 @@ public final class ChannelOutboundBuffer { private static final FastThreadLocal NIO_BUFFERS = new FastThreadLocal() { @Override protected ByteBuffer[] initialValue() throws Exception { - // Use 1024 as this is the IOV_MAX value on linux. If you sue a bigger one the JDK may do some array - // copy which we should not trigger. - // - // See 'man 2 writev' for more informations. return new ByteBuffer[1024]; } }; @@ -359,8 +355,8 @@ public final class ChannelOutboundBuffer { int count = buf.nioBufferCount(); int neededSpace = nioBufferCount + count; if (neededSpace > nioBuffers.length) { - // We have not enough space left in the array to add the ByteBuffers so break here. - break; + nioBuffers = expandNioBufferArray(nioBuffers, neededSpace, nioBufferCount); + NIO_BUFFERS.set(threadLocalMap, nioBuffers); } if (count == 1) { ByteBuffer nioBuf = buf.internalNioBuffer(readerIndex, readableBytes); @@ -389,6 +385,25 @@ public final class ChannelOutboundBuffer { return nioBufferCount; } + private static ByteBuffer[] expandNioBufferArray(ByteBuffer[] array, int neededSpace, int size) { + int newCapacity = array.length; + do { + // double capacity until it is big enough + // See https://github.com/netty/netty/issues/1890 + newCapacity <<= 1; + + if (newCapacity < 0) { + throw new IllegalStateException(); + } + + } while (neededSpace > newCapacity); + + ByteBuffer[] newArray = new ByteBuffer[newCapacity]; + System.arraycopy(array, 0, newArray, 0, size); + + return newArray; + } + /** * Returns the number of {@link ByteBuffer} that can be written out of the {@link ByteBuffer} array that was * obtained via {@link #nioBuffers()}. This method MUST be called after {@link #nioBuffers()}