diff --git a/buffer/src/main/java/io/netty/buffer/AbstractByteBufAllocator.java b/buffer/src/main/java/io/netty/buffer/AbstractByteBufAllocator.java index 34e5d2c6dd..eb445e17f2 100644 --- a/buffer/src/main/java/io/netty/buffer/AbstractByteBufAllocator.java +++ b/buffer/src/main/java/io/netty/buffer/AbstractByteBufAllocator.java @@ -26,7 +26,7 @@ import io.netty.util.internal.StringUtil; */ public abstract class AbstractByteBufAllocator implements ByteBufAllocator { private static final int DEFAULT_INITIAL_CAPACITY = 256; - private static final int DEFAULT_MAX_COMPONENTS = 16; + static final int DEFAULT_MAX_COMPONENTS = 16; protected static ByteBuf toLeakAwareBuffer(ByteBuf buf) { ResourceLeak leak; @@ -48,6 +48,28 @@ public abstract class AbstractByteBufAllocator implements ByteBufAllocator { return buf; } + protected static CompositeByteBuf toLeakAwareBuffer(CompositeByteBuf buf) { + ResourceLeak leak; + switch (ResourceLeakDetector.getLevel()) { + case SIMPLE: + leak = AbstractByteBuf.leakDetector.open(buf); + if (leak != null) { + buf = new SimpleLeakAwareCompositeByteBuf(buf, leak); + } + break; + case ADVANCED: + case PARANOID: + leak = AbstractByteBuf.leakDetector.open(buf); + if (leak != null) { + buf = new AdvancedLeakAwareCompositeByteBuf(buf, leak); + } + break; + default: + break; + } + return buf; + } + private final boolean directByDefault; private final ByteBuf emptyBuf; @@ -178,7 +200,7 @@ public abstract class AbstractByteBufAllocator implements ByteBufAllocator { @Override public CompositeByteBuf compositeHeapBuffer(int maxNumComponents) { - return new CompositeByteBuf(this, false, maxNumComponents); + return toLeakAwareBuffer(new CompositeByteBuf(this, false, maxNumComponents)); } @Override @@ -188,7 +210,7 @@ public abstract class AbstractByteBufAllocator implements ByteBufAllocator { @Override public CompositeByteBuf compositeDirectBuffer(int maxNumComponents) { - return new CompositeByteBuf(this, true, maxNumComponents); + return toLeakAwareBuffer(new CompositeByteBuf(this, true, maxNumComponents)); } private static void validate(int initialCapacity, int maxCapacity) { diff --git a/buffer/src/main/java/io/netty/buffer/AbstractReferenceCountedByteBuf.java b/buffer/src/main/java/io/netty/buffer/AbstractReferenceCountedByteBuf.java index 1f37cee9c6..c54b209974 100644 --- a/buffer/src/main/java/io/netty/buffer/AbstractReferenceCountedByteBuf.java +++ b/buffer/src/main/java/io/netty/buffer/AbstractReferenceCountedByteBuf.java @@ -44,7 +44,7 @@ public abstract class AbstractReferenceCountedByteBuf extends AbstractByteBuf { } @Override - public final int refCnt() { + public int refCnt() { return refCnt; } @@ -94,7 +94,7 @@ public abstract class AbstractReferenceCountedByteBuf extends AbstractByteBuf { } @Override - public final boolean release() { + public boolean release() { for (;;) { int refCnt = this.refCnt; if (refCnt == 0) { @@ -112,7 +112,7 @@ public abstract class AbstractReferenceCountedByteBuf extends AbstractByteBuf { } @Override - public final boolean release(int decrement) { + public boolean release(int decrement) { if (decrement <= 0) { throw new IllegalArgumentException("decrement: " + decrement + " (expected: > 0)"); } diff --git a/buffer/src/main/java/io/netty/buffer/AdvancedLeakAwareByteBuf.java b/buffer/src/main/java/io/netty/buffer/AdvancedLeakAwareByteBuf.java index 485b704f7b..79d6a7f53d 100644 --- a/buffer/src/main/java/io/netty/buffer/AdvancedLeakAwareByteBuf.java +++ b/buffer/src/main/java/io/netty/buffer/AdvancedLeakAwareByteBuf.java @@ -74,7 +74,7 @@ final class AdvancedLeakAwareByteBuf extends WrappedByteBuf { return deallocated; } - private void recordLeakNonRefCountingOperation() { + static void recordLeakNonRefCountingOperation(ResourceLeak leak) { if (!ACQUIRE_AND_RELEASE_ONLY) { leak.record(); } @@ -82,7 +82,7 @@ final class AdvancedLeakAwareByteBuf extends WrappedByteBuf { @Override public ByteBuf order(ByteOrder endianness) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); if (order() == endianness) { return this; } else { @@ -92,637 +92,637 @@ final class AdvancedLeakAwareByteBuf extends WrappedByteBuf { @Override public ByteBuf slice() { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return new AdvancedLeakAwareByteBuf(super.slice(), leak); } @Override public ByteBuf slice(int index, int length) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return new AdvancedLeakAwareByteBuf(super.slice(index, length), leak); } @Override public ByteBuf duplicate() { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return new AdvancedLeakAwareByteBuf(super.duplicate(), leak); } @Override public ByteBuf readSlice(int length) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return new AdvancedLeakAwareByteBuf(super.readSlice(length), leak); } @Override public ByteBuf discardReadBytes() { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.discardReadBytes(); } @Override public ByteBuf discardSomeReadBytes() { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.discardSomeReadBytes(); } @Override public ByteBuf ensureWritable(int minWritableBytes) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.ensureWritable(minWritableBytes); } @Override public int ensureWritable(int minWritableBytes, boolean force) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.ensureWritable(minWritableBytes, force); } @Override public boolean getBoolean(int index) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.getBoolean(index); } @Override public byte getByte(int index) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.getByte(index); } @Override public short getUnsignedByte(int index) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.getUnsignedByte(index); } @Override public short getShort(int index) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.getShort(index); } @Override public int getUnsignedShort(int index) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.getUnsignedShort(index); } @Override public int getMedium(int index) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.getMedium(index); } @Override public int getUnsignedMedium(int index) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.getUnsignedMedium(index); } @Override public int getInt(int index) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.getInt(index); } @Override public long getUnsignedInt(int index) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.getUnsignedInt(index); } @Override public long getLong(int index) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.getLong(index); } @Override public char getChar(int index) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.getChar(index); } @Override public float getFloat(int index) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.getFloat(index); } @Override public double getDouble(int index) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.getDouble(index); } @Override public ByteBuf getBytes(int index, ByteBuf dst) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.getBytes(index, dst); } @Override public ByteBuf getBytes(int index, ByteBuf dst, int length) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.getBytes(index, dst, length); } @Override public ByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.getBytes(index, dst, dstIndex, length); } @Override public ByteBuf getBytes(int index, byte[] dst) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.getBytes(index, dst); } @Override public ByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.getBytes(index, dst, dstIndex, length); } @Override public ByteBuf getBytes(int index, ByteBuffer dst) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.getBytes(index, dst); } @Override public ByteBuf getBytes(int index, OutputStream out, int length) throws IOException { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.getBytes(index, out, length); } @Override public int getBytes(int index, GatheringByteChannel out, int length) throws IOException { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.getBytes(index, out, length); } @Override public ByteBuf setBoolean(int index, boolean value) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.setBoolean(index, value); } @Override public ByteBuf setByte(int index, int value) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.setByte(index, value); } @Override public ByteBuf setShort(int index, int value) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.setShort(index, value); } @Override public ByteBuf setMedium(int index, int value) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.setMedium(index, value); } @Override public ByteBuf setInt(int index, int value) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.setInt(index, value); } @Override public ByteBuf setLong(int index, long value) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.setLong(index, value); } @Override public ByteBuf setChar(int index, int value) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.setChar(index, value); } @Override public ByteBuf setFloat(int index, float value) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.setFloat(index, value); } @Override public ByteBuf setDouble(int index, double value) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.setDouble(index, value); } @Override public ByteBuf setBytes(int index, ByteBuf src) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.setBytes(index, src); } @Override public ByteBuf setBytes(int index, ByteBuf src, int length) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.setBytes(index, src, length); } @Override public ByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.setBytes(index, src, srcIndex, length); } @Override public ByteBuf setBytes(int index, byte[] src) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.setBytes(index, src); } @Override public ByteBuf setBytes(int index, byte[] src, int srcIndex, int length) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.setBytes(index, src, srcIndex, length); } @Override public ByteBuf setBytes(int index, ByteBuffer src) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.setBytes(index, src); } @Override public int setBytes(int index, InputStream in, int length) throws IOException { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.setBytes(index, in, length); } @Override public int setBytes(int index, ScatteringByteChannel in, int length) throws IOException { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.setBytes(index, in, length); } @Override public ByteBuf setZero(int index, int length) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.setZero(index, length); } @Override public boolean readBoolean() { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.readBoolean(); } @Override public byte readByte() { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.readByte(); } @Override public short readUnsignedByte() { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.readUnsignedByte(); } @Override public short readShort() { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.readShort(); } @Override public int readUnsignedShort() { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.readUnsignedShort(); } @Override public int readMedium() { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.readMedium(); } @Override public int readUnsignedMedium() { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.readUnsignedMedium(); } @Override public int readInt() { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.readInt(); } @Override public long readUnsignedInt() { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.readUnsignedInt(); } @Override public long readLong() { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.readLong(); } @Override public char readChar() { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.readChar(); } @Override public float readFloat() { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.readFloat(); } @Override public double readDouble() { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.readDouble(); } @Override public ByteBuf readBytes(int length) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.readBytes(length); } @Override public ByteBuf readBytes(ByteBuf dst) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.readBytes(dst); } @Override public ByteBuf readBytes(ByteBuf dst, int length) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.readBytes(dst, length); } @Override public ByteBuf readBytes(ByteBuf dst, int dstIndex, int length) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.readBytes(dst, dstIndex, length); } @Override public ByteBuf readBytes(byte[] dst) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.readBytes(dst); } @Override public ByteBuf readBytes(byte[] dst, int dstIndex, int length) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.readBytes(dst, dstIndex, length); } @Override public ByteBuf readBytes(ByteBuffer dst) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.readBytes(dst); } @Override public ByteBuf readBytes(OutputStream out, int length) throws IOException { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.readBytes(out, length); } @Override public int readBytes(GatheringByteChannel out, int length) throws IOException { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.readBytes(out, length); } @Override public ByteBuf skipBytes(int length) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.skipBytes(length); } @Override public ByteBuf writeBoolean(boolean value) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.writeBoolean(value); } @Override public ByteBuf writeByte(int value) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.writeByte(value); } @Override public ByteBuf writeShort(int value) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.writeShort(value); } @Override public ByteBuf writeMedium(int value) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.writeMedium(value); } @Override public ByteBuf writeInt(int value) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.writeInt(value); } @Override public ByteBuf writeLong(long value) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.writeLong(value); } @Override public ByteBuf writeChar(int value) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.writeChar(value); } @Override public ByteBuf writeFloat(float value) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.writeFloat(value); } @Override public ByteBuf writeDouble(double value) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.writeDouble(value); } @Override public ByteBuf writeBytes(ByteBuf src) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.writeBytes(src); } @Override public ByteBuf writeBytes(ByteBuf src, int length) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.writeBytes(src, length); } @Override public ByteBuf writeBytes(ByteBuf src, int srcIndex, int length) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.writeBytes(src, srcIndex, length); } @Override public ByteBuf writeBytes(byte[] src) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.writeBytes(src); } @Override public ByteBuf writeBytes(byte[] src, int srcIndex, int length) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.writeBytes(src, srcIndex, length); } @Override public ByteBuf writeBytes(ByteBuffer src) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.writeBytes(src); } @Override public int writeBytes(InputStream in, int length) throws IOException { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.writeBytes(in, length); } @Override public int writeBytes(ScatteringByteChannel in, int length) throws IOException { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.writeBytes(in, length); } @Override public ByteBuf writeZero(int length) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.writeZero(length); } @Override public int indexOf(int fromIndex, int toIndex, byte value) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.indexOf(fromIndex, toIndex, value); } @Override public int bytesBefore(byte value) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.bytesBefore(value); } @Override public int bytesBefore(int length, byte value) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.bytesBefore(length, value); } @Override public int bytesBefore(int index, int length, byte value) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.bytesBefore(index, length, value); } @Override public int forEachByte(ByteBufProcessor processor) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.forEachByte(processor); } @Override public int forEachByte(int index, int length, ByteBufProcessor processor) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.forEachByte(index, length, processor); } @Override public int forEachByteDesc(ByteBufProcessor processor) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.forEachByteDesc(processor); } @Override public int forEachByteDesc(int index, int length, ByteBufProcessor processor) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.forEachByteDesc(index, length, processor); } @Override public ByteBuf copy() { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.copy(); } @Override public ByteBuf copy(int index, int length) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.copy(index, length); } @Override public int nioBufferCount() { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.nioBufferCount(); } @Override public ByteBuffer nioBuffer() { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.nioBuffer(); } @Override public ByteBuffer nioBuffer(int index, int length) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.nioBuffer(index, length); } @Override public ByteBuffer[] nioBuffers() { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.nioBuffers(); } @Override public ByteBuffer[] nioBuffers(int index, int length) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.nioBuffers(index, length); } @Override public ByteBuffer internalNioBuffer(int index, int length) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.internalNioBuffer(index, length); } @Override public String toString(Charset charset) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.toString(charset); } @Override public String toString(int index, int length, Charset charset) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.toString(index, length, charset); } @@ -740,7 +740,7 @@ final class AdvancedLeakAwareByteBuf extends WrappedByteBuf { @Override public ByteBuf capacity(int newCapacity) { - recordLeakNonRefCountingOperation(); + recordLeakNonRefCountingOperation(leak); return super.capacity(newCapacity); } } diff --git a/buffer/src/main/java/io/netty/buffer/AdvancedLeakAwareCompositeByteBuf.java b/buffer/src/main/java/io/netty/buffer/AdvancedLeakAwareCompositeByteBuf.java new file mode 100644 index 0000000000..0efb9e0c1a --- /dev/null +++ b/buffer/src/main/java/io/netty/buffer/AdvancedLeakAwareCompositeByteBuf.java @@ -0,0 +1,806 @@ +/* + * Copyright 2016 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.buffer; + + +import io.netty.util.ResourceLeak; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.channels.GatheringByteChannel; +import java.nio.channels.ScatteringByteChannel; +import java.nio.charset.Charset; +import java.util.Iterator; +import java.util.List; + +import static io.netty.buffer.AdvancedLeakAwareByteBuf.recordLeakNonRefCountingOperation; + +final class AdvancedLeakAwareCompositeByteBuf extends WrappedCompositeByteBuf { + + private final ResourceLeak leak; + + AdvancedLeakAwareCompositeByteBuf(CompositeByteBuf wrapped, ResourceLeak leak) { + super(wrapped); + this.leak = leak; + } + + @Override + public ByteBuf order(ByteOrder endianness) { + recordLeakNonRefCountingOperation(leak); + if (order() == endianness) { + return this; + } else { + return new AdvancedLeakAwareByteBuf(super.order(endianness), leak); + } + } + + @Override + public ByteBuf slice() { + recordLeakNonRefCountingOperation(leak); + return new AdvancedLeakAwareByteBuf(super.slice(), leak); + } + + @Override + public ByteBuf slice(int index, int length) { + recordLeakNonRefCountingOperation(leak); + return new AdvancedLeakAwareByteBuf(super.slice(index, length), leak); + } + + @Override + public ByteBuf duplicate() { + recordLeakNonRefCountingOperation(leak); + return new AdvancedLeakAwareByteBuf(super.duplicate(), leak); + } + + @Override + public ByteBuf readSlice(int length) { + recordLeakNonRefCountingOperation(leak); + return new AdvancedLeakAwareByteBuf(super.readSlice(length), leak); + } + + @Override + public CompositeByteBuf discardReadBytes() { + recordLeakNonRefCountingOperation(leak); + return super.discardReadBytes(); + } + + @Override + public CompositeByteBuf discardSomeReadBytes() { + recordLeakNonRefCountingOperation(leak); + return super.discardSomeReadBytes(); + } + + @Override + public CompositeByteBuf ensureWritable(int minWritableBytes) { + recordLeakNonRefCountingOperation(leak); + return super.ensureWritable(minWritableBytes); + } + + @Override + public int ensureWritable(int minWritableBytes, boolean force) { + recordLeakNonRefCountingOperation(leak); + return super.ensureWritable(minWritableBytes, force); + } + + @Override + public boolean getBoolean(int index) { + recordLeakNonRefCountingOperation(leak); + return super.getBoolean(index); + } + + @Override + public byte getByte(int index) { + recordLeakNonRefCountingOperation(leak); + return super.getByte(index); + } + + @Override + public short getUnsignedByte(int index) { + recordLeakNonRefCountingOperation(leak); + return super.getUnsignedByte(index); + } + + @Override + public short getShort(int index) { + recordLeakNonRefCountingOperation(leak); + return super.getShort(index); + } + + @Override + public int getUnsignedShort(int index) { + recordLeakNonRefCountingOperation(leak); + return super.getUnsignedShort(index); + } + + @Override + public int getMedium(int index) { + recordLeakNonRefCountingOperation(leak); + return super.getMedium(index); + } + + @Override + public int getUnsignedMedium(int index) { + recordLeakNonRefCountingOperation(leak); + return super.getUnsignedMedium(index); + } + + @Override + public int getInt(int index) { + recordLeakNonRefCountingOperation(leak); + return super.getInt(index); + } + + @Override + public long getUnsignedInt(int index) { + recordLeakNonRefCountingOperation(leak); + return super.getUnsignedInt(index); + } + + @Override + public long getLong(int index) { + recordLeakNonRefCountingOperation(leak); + return super.getLong(index); + } + + @Override + public char getChar(int index) { + recordLeakNonRefCountingOperation(leak); + return super.getChar(index); + } + + @Override + public float getFloat(int index) { + recordLeakNonRefCountingOperation(leak); + return super.getFloat(index); + } + + @Override + public double getDouble(int index) { + recordLeakNonRefCountingOperation(leak); + return super.getDouble(index); + } + + @Override + public CompositeByteBuf getBytes(int index, ByteBuf dst) { + recordLeakNonRefCountingOperation(leak); + return super.getBytes(index, dst); + } + + @Override + public CompositeByteBuf getBytes(int index, ByteBuf dst, int length) { + recordLeakNonRefCountingOperation(leak); + return super.getBytes(index, dst, length); + } + + @Override + public CompositeByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) { + recordLeakNonRefCountingOperation(leak); + return super.getBytes(index, dst, dstIndex, length); + } + + @Override + public CompositeByteBuf getBytes(int index, byte[] dst) { + recordLeakNonRefCountingOperation(leak); + return super.getBytes(index, dst); + } + + @Override + public CompositeByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) { + recordLeakNonRefCountingOperation(leak); + return super.getBytes(index, dst, dstIndex, length); + } + + @Override + public CompositeByteBuf getBytes(int index, ByteBuffer dst) { + recordLeakNonRefCountingOperation(leak); + return super.getBytes(index, dst); + } + + @Override + public CompositeByteBuf getBytes(int index, OutputStream out, int length) throws IOException { + recordLeakNonRefCountingOperation(leak); + return super.getBytes(index, out, length); + } + + @Override + public int getBytes(int index, GatheringByteChannel out, int length) throws IOException { + recordLeakNonRefCountingOperation(leak); + return super.getBytes(index, out, length); + } + + @Override + public CompositeByteBuf setBoolean(int index, boolean value) { + recordLeakNonRefCountingOperation(leak); + return super.setBoolean(index, value); + } + + @Override + public CompositeByteBuf setByte(int index, int value) { + recordLeakNonRefCountingOperation(leak); + return super.setByte(index, value); + } + + @Override + public CompositeByteBuf setShort(int index, int value) { + recordLeakNonRefCountingOperation(leak); + return super.setShort(index, value); + } + + @Override + public CompositeByteBuf setMedium(int index, int value) { + recordLeakNonRefCountingOperation(leak); + return super.setMedium(index, value); + } + + @Override + public CompositeByteBuf setInt(int index, int value) { + recordLeakNonRefCountingOperation(leak); + return super.setInt(index, value); + } + + @Override + public CompositeByteBuf setLong(int index, long value) { + recordLeakNonRefCountingOperation(leak); + return super.setLong(index, value); + } + + @Override + public CompositeByteBuf setChar(int index, int value) { + recordLeakNonRefCountingOperation(leak); + return super.setChar(index, value); + } + + @Override + public CompositeByteBuf setFloat(int index, float value) { + recordLeakNonRefCountingOperation(leak); + return super.setFloat(index, value); + } + + @Override + public CompositeByteBuf setDouble(int index, double value) { + recordLeakNonRefCountingOperation(leak); + return super.setDouble(index, value); + } + + @Override + public CompositeByteBuf setBytes(int index, ByteBuf src) { + recordLeakNonRefCountingOperation(leak); + return super.setBytes(index, src); + } + + @Override + public CompositeByteBuf setBytes(int index, ByteBuf src, int length) { + recordLeakNonRefCountingOperation(leak); + return super.setBytes(index, src, length); + } + + @Override + public CompositeByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) { + recordLeakNonRefCountingOperation(leak); + return super.setBytes(index, src, srcIndex, length); + } + + @Override + public CompositeByteBuf setBytes(int index, byte[] src) { + recordLeakNonRefCountingOperation(leak); + return super.setBytes(index, src); + } + + @Override + public CompositeByteBuf setBytes(int index, byte[] src, int srcIndex, int length) { + recordLeakNonRefCountingOperation(leak); + return super.setBytes(index, src, srcIndex, length); + } + + @Override + public CompositeByteBuf setBytes(int index, ByteBuffer src) { + recordLeakNonRefCountingOperation(leak); + return super.setBytes(index, src); + } + + @Override + public int setBytes(int index, InputStream in, int length) throws IOException { + recordLeakNonRefCountingOperation(leak); + return super.setBytes(index, in, length); + } + + @Override + public int setBytes(int index, ScatteringByteChannel in, int length) throws IOException { + recordLeakNonRefCountingOperation(leak); + return super.setBytes(index, in, length); + } + + @Override + public CompositeByteBuf setZero(int index, int length) { + recordLeakNonRefCountingOperation(leak); + return super.setZero(index, length); + } + + @Override + public boolean readBoolean() { + recordLeakNonRefCountingOperation(leak); + return super.readBoolean(); + } + + @Override + public byte readByte() { + recordLeakNonRefCountingOperation(leak); + return super.readByte(); + } + + @Override + public short readUnsignedByte() { + recordLeakNonRefCountingOperation(leak); + return super.readUnsignedByte(); + } + + @Override + public short readShort() { + recordLeakNonRefCountingOperation(leak); + return super.readShort(); + } + + @Override + public int readUnsignedShort() { + recordLeakNonRefCountingOperation(leak); + return super.readUnsignedShort(); + } + + @Override + public int readMedium() { + recordLeakNonRefCountingOperation(leak); + return super.readMedium(); + } + + @Override + public int readUnsignedMedium() { + recordLeakNonRefCountingOperation(leak); + return super.readUnsignedMedium(); + } + + @Override + public int readInt() { + recordLeakNonRefCountingOperation(leak); + return super.readInt(); + } + + @Override + public long readUnsignedInt() { + recordLeakNonRefCountingOperation(leak); + return super.readUnsignedInt(); + } + + @Override + public long readLong() { + recordLeakNonRefCountingOperation(leak); + return super.readLong(); + } + + @Override + public char readChar() { + recordLeakNonRefCountingOperation(leak); + return super.readChar(); + } + + @Override + public float readFloat() { + recordLeakNonRefCountingOperation(leak); + return super.readFloat(); + } + + @Override + public double readDouble() { + recordLeakNonRefCountingOperation(leak); + return super.readDouble(); + } + + @Override + public ByteBuf readBytes(int length) { + recordLeakNonRefCountingOperation(leak); + return super.readBytes(length); + } + + @Override + public CompositeByteBuf readBytes(ByteBuf dst) { + recordLeakNonRefCountingOperation(leak); + return super.readBytes(dst); + } + + @Override + public CompositeByteBuf readBytes(ByteBuf dst, int length) { + recordLeakNonRefCountingOperation(leak); + return super.readBytes(dst, length); + } + + @Override + public CompositeByteBuf readBytes(ByteBuf dst, int dstIndex, int length) { + recordLeakNonRefCountingOperation(leak); + return super.readBytes(dst, dstIndex, length); + } + + @Override + public CompositeByteBuf readBytes(byte[] dst) { + recordLeakNonRefCountingOperation(leak); + return super.readBytes(dst); + } + + @Override + public CompositeByteBuf readBytes(byte[] dst, int dstIndex, int length) { + recordLeakNonRefCountingOperation(leak); + return super.readBytes(dst, dstIndex, length); + } + + @Override + public CompositeByteBuf readBytes(ByteBuffer dst) { + recordLeakNonRefCountingOperation(leak); + return super.readBytes(dst); + } + + @Override + public CompositeByteBuf readBytes(OutputStream out, int length) throws IOException { + recordLeakNonRefCountingOperation(leak); + return super.readBytes(out, length); + } + + @Override + public int readBytes(GatheringByteChannel out, int length) throws IOException { + recordLeakNonRefCountingOperation(leak); + return super.readBytes(out, length); + } + + @Override + public CompositeByteBuf skipBytes(int length) { + recordLeakNonRefCountingOperation(leak); + return super.skipBytes(length); + } + + @Override + public CompositeByteBuf writeBoolean(boolean value) { + recordLeakNonRefCountingOperation(leak); + return super.writeBoolean(value); + } + + @Override + public CompositeByteBuf writeByte(int value) { + recordLeakNonRefCountingOperation(leak); + return super.writeByte(value); + } + + @Override + public CompositeByteBuf writeShort(int value) { + recordLeakNonRefCountingOperation(leak); + return super.writeShort(value); + } + + @Override + public CompositeByteBuf writeMedium(int value) { + recordLeakNonRefCountingOperation(leak); + return super.writeMedium(value); + } + + @Override + public CompositeByteBuf writeInt(int value) { + recordLeakNonRefCountingOperation(leak); + return super.writeInt(value); + } + + @Override + public CompositeByteBuf writeLong(long value) { + recordLeakNonRefCountingOperation(leak); + return super.writeLong(value); + } + + @Override + public CompositeByteBuf writeChar(int value) { + recordLeakNonRefCountingOperation(leak); + return super.writeChar(value); + } + + @Override + public CompositeByteBuf writeFloat(float value) { + recordLeakNonRefCountingOperation(leak); + return super.writeFloat(value); + } + + @Override + public CompositeByteBuf writeDouble(double value) { + recordLeakNonRefCountingOperation(leak); + return super.writeDouble(value); + } + + @Override + public CompositeByteBuf writeBytes(ByteBuf src) { + recordLeakNonRefCountingOperation(leak); + return super.writeBytes(src); + } + + @Override + public CompositeByteBuf writeBytes(ByteBuf src, int length) { + recordLeakNonRefCountingOperation(leak); + return super.writeBytes(src, length); + } + + @Override + public CompositeByteBuf writeBytes(ByteBuf src, int srcIndex, int length) { + recordLeakNonRefCountingOperation(leak); + return super.writeBytes(src, srcIndex, length); + } + + @Override + public CompositeByteBuf writeBytes(byte[] src) { + recordLeakNonRefCountingOperation(leak); + return super.writeBytes(src); + } + + @Override + public CompositeByteBuf writeBytes(byte[] src, int srcIndex, int length) { + recordLeakNonRefCountingOperation(leak); + return super.writeBytes(src, srcIndex, length); + } + + @Override + public CompositeByteBuf writeBytes(ByteBuffer src) { + recordLeakNonRefCountingOperation(leak); + return super.writeBytes(src); + } + + @Override + public int writeBytes(InputStream in, int length) throws IOException { + recordLeakNonRefCountingOperation(leak); + return super.writeBytes(in, length); + } + + @Override + public int writeBytes(ScatteringByteChannel in, int length) throws IOException { + recordLeakNonRefCountingOperation(leak); + return super.writeBytes(in, length); + } + + @Override + public CompositeByteBuf writeZero(int length) { + recordLeakNonRefCountingOperation(leak); + return super.writeZero(length); + } + + @Override + public int indexOf(int fromIndex, int toIndex, byte value) { + recordLeakNonRefCountingOperation(leak); + return super.indexOf(fromIndex, toIndex, value); + } + + @Override + public int bytesBefore(byte value) { + recordLeakNonRefCountingOperation(leak); + return super.bytesBefore(value); + } + + @Override + public int bytesBefore(int length, byte value) { + recordLeakNonRefCountingOperation(leak); + return super.bytesBefore(length, value); + } + + @Override + public int bytesBefore(int index, int length, byte value) { + recordLeakNonRefCountingOperation(leak); + return super.bytesBefore(index, length, value); + } + + @Override + public int forEachByte(ByteBufProcessor processor) { + recordLeakNonRefCountingOperation(leak); + return super.forEachByte(processor); + } + + @Override + public int forEachByte(int index, int length, ByteBufProcessor processor) { + recordLeakNonRefCountingOperation(leak); + return super.forEachByte(index, length, processor); + } + + @Override + public int forEachByteDesc(ByteBufProcessor processor) { + recordLeakNonRefCountingOperation(leak); + return super.forEachByteDesc(processor); + } + + @Override + public int forEachByteDesc(int index, int length, ByteBufProcessor processor) { + recordLeakNonRefCountingOperation(leak); + return super.forEachByteDesc(index, length, processor); + } + + @Override + public ByteBuf copy() { + recordLeakNonRefCountingOperation(leak); + return super.copy(); + } + + @Override + public ByteBuf copy(int index, int length) { + recordLeakNonRefCountingOperation(leak); + return super.copy(index, length); + } + + @Override + public int nioBufferCount() { + recordLeakNonRefCountingOperation(leak); + return super.nioBufferCount(); + } + + @Override + public ByteBuffer nioBuffer() { + recordLeakNonRefCountingOperation(leak); + return super.nioBuffer(); + } + + @Override + public ByteBuffer nioBuffer(int index, int length) { + recordLeakNonRefCountingOperation(leak); + return super.nioBuffer(index, length); + } + + @Override + public ByteBuffer[] nioBuffers() { + recordLeakNonRefCountingOperation(leak); + return super.nioBuffers(); + } + + @Override + public ByteBuffer[] nioBuffers(int index, int length) { + recordLeakNonRefCountingOperation(leak); + return super.nioBuffers(index, length); + } + + @Override + public ByteBuffer internalNioBuffer(int index, int length) { + recordLeakNonRefCountingOperation(leak); + return super.internalNioBuffer(index, length); + } + + @Override + public String toString(Charset charset) { + recordLeakNonRefCountingOperation(leak); + return super.toString(charset); + } + + @Override + public String toString(int index, int length, Charset charset) { + recordLeakNonRefCountingOperation(leak); + return super.toString(index, length, charset); + } + + @Override + public CompositeByteBuf capacity(int newCapacity) { + recordLeakNonRefCountingOperation(leak); + return super.capacity(newCapacity); + } + + @Override + public CompositeByteBuf addComponent(ByteBuf buffer) { + recordLeakNonRefCountingOperation(leak); + return super.addComponent(buffer); + } + + @Override + public CompositeByteBuf addComponents(ByteBuf... buffers) { + recordLeakNonRefCountingOperation(leak); + return super.addComponents(buffers); + } + + @Override + public CompositeByteBuf addComponents(Iterable buffers) { + recordLeakNonRefCountingOperation(leak); + return super.addComponents(buffers); + } + + @Override + public CompositeByteBuf addComponent(int cIndex, ByteBuf buffer) { + recordLeakNonRefCountingOperation(leak); + return super.addComponent(cIndex, buffer); + } + + @Override + public CompositeByteBuf addComponents(int cIndex, ByteBuf... buffers) { + recordLeakNonRefCountingOperation(leak); + return super.addComponents(cIndex, buffers); + } + + @Override + public CompositeByteBuf removeComponent(int cIndex) { + recordLeakNonRefCountingOperation(leak); + return super.removeComponent(cIndex); + } + + @Override + public CompositeByteBuf addComponents(int cIndex, Iterable buffers) { + recordLeakNonRefCountingOperation(leak); + return super.addComponents(cIndex, buffers); + } + + @Override + public CompositeByteBuf removeComponents(int cIndex, int numComponents) { + recordLeakNonRefCountingOperation(leak); + return super.removeComponents(cIndex, numComponents); + } + + @Override + public Iterator iterator() { + recordLeakNonRefCountingOperation(leak); + return super.iterator(); + } + + @Override + public List decompose(int offset, int length) { + recordLeakNonRefCountingOperation(leak); + return super.decompose(offset, length); + } + + @Override + public CompositeByteBuf consolidate() { + recordLeakNonRefCountingOperation(leak); + return super.consolidate(); + } + + @Override + public CompositeByteBuf discardReadComponents() { + recordLeakNonRefCountingOperation(leak); + return super.discardReadComponents(); + } + + @Override + public CompositeByteBuf consolidate(int cIndex, int numComponents) { + recordLeakNonRefCountingOperation(leak); + return super.consolidate(cIndex, numComponents); + } + + @Override + public CompositeByteBuf retain() { + leak.record(); + return super.retain(); + } + + @Override + public CompositeByteBuf retain(int increment) { + leak.record(); + return super.retain(increment); + } + + @Override + public boolean release() { + boolean deallocated = super.release(); + if (deallocated) { + leak.close(); + } else { + leak.record(); + } + return deallocated; + } + + @Override + public boolean release(int decrement) { + boolean deallocated = super.release(decrement); + if (deallocated) { + leak.close(); + } else { + leak.record(); + } + return deallocated; + } +} diff --git a/buffer/src/main/java/io/netty/buffer/CompositeByteBuf.java b/buffer/src/main/java/io/netty/buffer/CompositeByteBuf.java index c141d2833e..b57467534e 100644 --- a/buffer/src/main/java/io/netty/buffer/CompositeByteBuf.java +++ b/buffer/src/main/java/io/netty/buffer/CompositeByteBuf.java @@ -15,7 +15,6 @@ */ package io.netty.buffer; -import io.netty.util.ResourceLeak; import io.netty.util.internal.EmptyArrays; import java.io.IOException; @@ -44,10 +43,9 @@ public class CompositeByteBuf extends AbstractReferenceCountedByteBuf implements private static final ByteBuffer EMPTY_NIO_BUFFER = Unpooled.EMPTY_BUFFER.nioBuffer(); private static final Iterator EMPTY_ITERATOR = Collections.emptyList().iterator(); - private final ResourceLeak leak; private final ByteBufAllocator alloc; private final boolean direct; - private final List components = new ArrayList(); + private final List components; private final int maxNumComponents; private boolean freed; @@ -60,7 +58,7 @@ public class CompositeByteBuf extends AbstractReferenceCountedByteBuf implements this.alloc = alloc; this.direct = direct; this.maxNumComponents = maxNumComponents; - leak = leakDetector.open(this); + components = newList(maxNumComponents); } public CompositeByteBuf(ByteBufAllocator alloc, boolean direct, int maxNumComponents, ByteBuf... buffers) { @@ -76,11 +74,11 @@ public class CompositeByteBuf extends AbstractReferenceCountedByteBuf implements this.alloc = alloc; this.direct = direct; this.maxNumComponents = maxNumComponents; + components = newList(maxNumComponents); addComponents0(0, buffers); consolidateIfNeeded(); setIndex(0, capacity()); - leak = leakDetector.open(this); } public CompositeByteBuf( @@ -97,10 +95,24 @@ public class CompositeByteBuf extends AbstractReferenceCountedByteBuf implements this.alloc = alloc; this.direct = direct; this.maxNumComponents = maxNumComponents; + components = newList(maxNumComponents); + addComponents0(0, buffers); consolidateIfNeeded(); setIndex(0, capacity()); - leak = leakDetector.open(this); + } + + private static List newList(int maxNumComponents) { + return new ArrayList(Math.min(AbstractByteBufAllocator.DEFAULT_MAX_COMPONENTS, maxNumComponents)); + } + + // Special constructor used by WrappedCompositeByteBuf + CompositeByteBuf(ByteBufAllocator alloc) { + super(Integer.MAX_VALUE); + this.alloc = alloc; + direct = false; + maxNumComponents = 0; + components = Collections.emptyList(); } /** @@ -1624,10 +1636,6 @@ public class CompositeByteBuf extends AbstractReferenceCountedByteBuf implements for (int i = 0; i < size; i++) { components.get(i).freeIfNecessary(); } - - if (leak != null) { - leak.close(); - } } @Override diff --git a/buffer/src/main/java/io/netty/buffer/SimpleLeakAwareCompositeByteBuf.java b/buffer/src/main/java/io/netty/buffer/SimpleLeakAwareCompositeByteBuf.java new file mode 100644 index 0000000000..bede44fee5 --- /dev/null +++ b/buffer/src/main/java/io/netty/buffer/SimpleLeakAwareCompositeByteBuf.java @@ -0,0 +1,79 @@ +/* + * Copyright 2016 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.buffer; + + +import io.netty.util.ResourceLeak; + +import java.nio.ByteOrder; + +final class SimpleLeakAwareCompositeByteBuf extends WrappedCompositeByteBuf { + + private final ResourceLeak leak; + + SimpleLeakAwareCompositeByteBuf(CompositeByteBuf wrapped, ResourceLeak leak) { + super(wrapped); + this.leak = leak; + } + + @Override + public boolean release() { + boolean deallocated = super.release(); + if (deallocated) { + leak.close(); + } + return deallocated; + } + + @Override + public boolean release(int decrement) { + boolean deallocated = super.release(decrement); + if (deallocated) { + leak.close(); + } + return deallocated; + } + + @Override + public ByteBuf order(ByteOrder endianness) { + leak.record(); + if (order() == endianness) { + return this; + } else { + return new SimpleLeakAwareByteBuf(super.order(endianness), leak); + } + } + + @Override + public ByteBuf slice() { + return new SimpleLeakAwareByteBuf(super.slice(), leak); + } + + @Override + public ByteBuf slice(int index, int length) { + return new SimpleLeakAwareByteBuf(super.slice(index, length), leak); + } + + @Override + public ByteBuf duplicate() { + return new SimpleLeakAwareByteBuf(super.duplicate(), leak); + } + + @Override + public ByteBuf readSlice(int length) { + return new SimpleLeakAwareByteBuf(super.readSlice(length), leak); + } +} diff --git a/buffer/src/main/java/io/netty/buffer/Unpooled.java b/buffer/src/main/java/io/netty/buffer/Unpooled.java index 10baa6be79..0532c0c6a1 100644 --- a/buffer/src/main/java/io/netty/buffer/Unpooled.java +++ b/buffer/src/main/java/io/netty/buffer/Unpooled.java @@ -230,7 +230,7 @@ public final class Unpooled { * content will be visible to the returned buffer. */ public static ByteBuf wrappedBuffer(byte[]... arrays) { - return wrappedBuffer(16, arrays); + return wrappedBuffer(AbstractByteBufAllocator.DEFAULT_MAX_COMPONENTS, arrays); } /** @@ -241,7 +241,7 @@ public final class Unpooled { * @return The readable portion of the {@code buffers}. The caller is responsible for releasing this buffer. */ public static ByteBuf wrappedBuffer(ByteBuf... buffers) { - return wrappedBuffer(16, buffers); + return wrappedBuffer(AbstractByteBufAllocator.DEFAULT_MAX_COMPONENTS, buffers); } /** @@ -250,7 +250,7 @@ public final class Unpooled { * specified buffers will be visible to the returned buffer. */ public static ByteBuf wrappedBuffer(ByteBuffer... buffers) { - return wrappedBuffer(16, buffers); + return wrappedBuffer(AbstractByteBufAllocator.DEFAULT_MAX_COMPONENTS, buffers); } /** @@ -358,7 +358,7 @@ public final class Unpooled { * Returns a new big-endian composite buffer with no components. */ public static CompositeByteBuf compositeBuffer() { - return compositeBuffer(16); + return compositeBuffer(AbstractByteBufAllocator.DEFAULT_MAX_COMPONENTS); } /** diff --git a/buffer/src/main/java/io/netty/buffer/WrappedCompositeByteBuf.java b/buffer/src/main/java/io/netty/buffer/WrappedCompositeByteBuf.java new file mode 100644 index 0000000000..cc4a5da379 --- /dev/null +++ b/buffer/src/main/java/io/netty/buffer/WrappedCompositeByteBuf.java @@ -0,0 +1,994 @@ +/* + * Copyright 2016 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.buffer; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.channels.GatheringByteChannel; +import java.nio.channels.ScatteringByteChannel; +import java.nio.charset.Charset; +import java.util.Iterator; +import java.util.List; + +class WrappedCompositeByteBuf extends CompositeByteBuf { + + private final CompositeByteBuf wrapped; + + WrappedCompositeByteBuf(CompositeByteBuf wrapped) { + super(wrapped.alloc()); + this.wrapped = wrapped; + } + + @Override + public boolean release() { + return wrapped.release(); + } + + @Override + public boolean release(int decrement) { + return wrapped.release(decrement); + } + + @Override + public final int maxCapacity() { + return wrapped.maxCapacity(); + } + + @Override + public final int readerIndex() { + return wrapped.readerIndex(); + } + + @Override + public final int writerIndex() { + return wrapped.writerIndex(); + } + + @Override + public final boolean isReadable() { + return wrapped.isReadable(); + } + + @Override + public final boolean isReadable(int numBytes) { + return wrapped.isReadable(numBytes); + } + + @Override + public final boolean isWritable() { + return wrapped.isWritable(); + } + + @Override + public final boolean isWritable(int numBytes) { + return wrapped.isWritable(numBytes); + } + + @Override + public final int readableBytes() { + return wrapped.readableBytes(); + } + + @Override + public final int writableBytes() { + return wrapped.writableBytes(); + } + + @Override + public final int maxWritableBytes() { + return wrapped.maxWritableBytes(); + } + + @Override + public int ensureWritable(int minWritableBytes, boolean force) { + return wrapped.ensureWritable(minWritableBytes, force); + } + + @Override + public ByteBuf order(ByteOrder endianness) { + return wrapped.order(endianness); + } + + @Override + public boolean getBoolean(int index) { + return wrapped.getBoolean(index); + } + + @Override + public short getUnsignedByte(int index) { + return wrapped.getUnsignedByte(index); + } + + @Override + public short getShort(int index) { + return wrapped.getShort(index); + } + + @Override + public int getUnsignedShort(int index) { + return wrapped.getUnsignedShort(index); + } + + @Override + public int getUnsignedMedium(int index) { + return wrapped.getUnsignedMedium(index); + } + + @Override + public int getMedium(int index) { + return wrapped.getMedium(index); + } + + @Override + public int getInt(int index) { + return wrapped.getInt(index); + } + + @Override + public long getUnsignedInt(int index) { + return wrapped.getUnsignedInt(index); + } + + @Override + public long getLong(int index) { + return wrapped.getLong(index); + } + + @Override + public char getChar(int index) { + return wrapped.getChar(index); + } + + @Override + public float getFloat(int index) { + return wrapped.getFloat(index); + } + + @Override + public double getDouble(int index) { + return wrapped.getDouble(index); + } + + @Override + public byte readByte() { + return wrapped.readByte(); + } + + @Override + public boolean readBoolean() { + return wrapped.readBoolean(); + } + + @Override + public short readUnsignedByte() { + return wrapped.readUnsignedByte(); + } + + @Override + public short readShort() { + return wrapped.readShort(); + } + + @Override + public int readUnsignedShort() { + return wrapped.readUnsignedShort(); + } + + @Override + public int readMedium() { + return wrapped.readMedium(); + } + + @Override + public int readUnsignedMedium() { + return wrapped.readUnsignedMedium(); + } + + @Override + public int readInt() { + return wrapped.readInt(); + } + + @Override + public long readUnsignedInt() { + return wrapped.readUnsignedInt(); + } + + @Override + public long readLong() { + return wrapped.readLong(); + } + + @Override + public char readChar() { + return wrapped.readChar(); + } + + @Override + public float readFloat() { + return wrapped.readFloat(); + } + + @Override + public double readDouble() { + return wrapped.readDouble(); + } + + @Override + public ByteBuf readBytes(int length) { + return wrapped.readBytes(length); + } + + @Override + public ByteBuf slice() { + return wrapped.slice(); + } + + @Override + public ByteBuf slice(int index, int length) { + return wrapped.slice(index, length); + } + + @Override + public ByteBuffer nioBuffer() { + return wrapped.nioBuffer(); + } + + @Override + public String toString(Charset charset) { + return wrapped.toString(charset); + } + + @Override + public String toString(int index, int length, Charset charset) { + return wrapped.toString(index, length, charset); + } + + @Override + public int indexOf(int fromIndex, int toIndex, byte value) { + return wrapped.indexOf(fromIndex, toIndex, value); + } + + @Override + public int bytesBefore(byte value) { + return wrapped.bytesBefore(value); + } + + @Override + public int bytesBefore(int length, byte value) { + return wrapped.bytesBefore(length, value); + } + + @Override + public int bytesBefore(int index, int length, byte value) { + return wrapped.bytesBefore(index, length, value); + } + + @Override + public int forEachByte(ByteBufProcessor processor) { + return wrapped.forEachByte(processor); + } + + @Override + public int forEachByte(int index, int length, ByteBufProcessor processor) { + return wrapped.forEachByte(index, length, processor); + } + + @Override + public int forEachByteDesc(ByteBufProcessor processor) { + return wrapped.forEachByteDesc(processor); + } + + @Override + public int forEachByteDesc(int index, int length, ByteBufProcessor processor) { + return wrapped.forEachByteDesc(index, length, processor); + } + + @Override + public final int hashCode() { + return wrapped.hashCode(); + } + + @Override + public final boolean equals(Object o) { + return wrapped.equals(o); + } + + @Override + public final int compareTo(ByteBuf that) { + return wrapped.compareTo(that); + } + + @Override + public final int refCnt() { + return wrapped.refCnt(); + } + + @Override + public ByteBuf duplicate() { + return wrapped.duplicate(); + } + + @Override + public ByteBuf readSlice(int length) { + return wrapped.readSlice(length); + } + + @Override + public int readBytes(GatheringByteChannel out, int length) throws IOException { + return wrapped.readBytes(out, length); + } + + @Override + public int writeBytes(InputStream in, int length) throws IOException { + return wrapped.writeBytes(in, length); + } + + @Override + public int writeBytes(ScatteringByteChannel in, int length) throws IOException { + return wrapped.writeBytes(in, length); + } + + @Override + public ByteBuf copy() { + return wrapped.copy(); + } + + @Override + public CompositeByteBuf addComponent(ByteBuf buffer) { + wrapped.addComponent(buffer); + return this; + } + + @Override + public CompositeByteBuf addComponents(ByteBuf... buffers) { + wrapped.addComponents(buffers); + return this; + } + + @Override + public CompositeByteBuf addComponents(Iterable buffers) { + wrapped.addComponents(buffers); + return this; + } + + @Override + public CompositeByteBuf addComponent(int cIndex, ByteBuf buffer) { + wrapped.addComponent(cIndex, buffer); + return this; + } + + @Override + public CompositeByteBuf addComponents(int cIndex, ByteBuf... buffers) { + wrapped.addComponents(cIndex, buffers); + return this; + } + + @Override + public CompositeByteBuf addComponents(int cIndex, Iterable buffers) { + wrapped.addComponents(cIndex, buffers); + return this; + } + + @Override + public CompositeByteBuf removeComponent(int cIndex) { + wrapped.removeComponent(cIndex); + return this; + } + + @Override + public CompositeByteBuf removeComponents(int cIndex, int numComponents) { + wrapped.removeComponents(cIndex, numComponents); + return this; + } + + @Override + public Iterator iterator() { + return wrapped.iterator(); + } + + @Override + public List decompose(int offset, int length) { + return wrapped.decompose(offset, length); + } + + @Override + public final boolean isDirect() { + return wrapped.isDirect(); + } + + @Override + public final boolean hasArray() { + return wrapped.hasArray(); + } + + @Override + public final byte[] array() { + return wrapped.array(); + } + + @Override + public final int arrayOffset() { + return wrapped.arrayOffset(); + } + + @Override + public final boolean hasMemoryAddress() { + return wrapped.hasMemoryAddress(); + } + + @Override + public final long memoryAddress() { + return wrapped.memoryAddress(); + } + + @Override + public final int capacity() { + return wrapped.capacity(); + } + + @Override + public CompositeByteBuf capacity(int newCapacity) { + wrapped.capacity(newCapacity); + return this; + } + + @Override + public final ByteBufAllocator alloc() { + return wrapped.alloc(); + } + + @Override + public final ByteOrder order() { + return wrapped.order(); + } + + @Override + public final int numComponents() { + return wrapped.numComponents(); + } + + @Override + public final int maxNumComponents() { + return wrapped.maxNumComponents(); + } + + @Override + public final int toComponentIndex(int offset) { + return wrapped.toComponentIndex(offset); + } + + @Override + public final int toByteIndex(int cIndex) { + return wrapped.toByteIndex(cIndex); + } + + @Override + public byte getByte(int index) { + return wrapped.getByte(index); + } + + @Override + protected final byte _getByte(int index) { + return wrapped._getByte(index); + } + + @Override + protected final short _getShort(int index) { + return wrapped._getShort(index); + } + + @Override + protected final int _getUnsignedMedium(int index) { + return wrapped._getUnsignedMedium(index); + } + + @Override + protected final int _getInt(int index) { + return wrapped._getInt(index); + } + + @Override + protected final long _getLong(int index) { + return wrapped._getLong(index); + } + + @Override + public CompositeByteBuf getBytes(int index, byte[] dst, int dstIndex, int length) { + wrapped.getBytes(index, dst, dstIndex, length); + return this; + } + + @Override + public CompositeByteBuf getBytes(int index, ByteBuffer dst) { + wrapped.getBytes(index, dst); + return this; + } + + @Override + public CompositeByteBuf getBytes(int index, ByteBuf dst, int dstIndex, int length) { + wrapped.getBytes(index, dst, dstIndex, length); + return this; + } + + @Override + public int getBytes(int index, GatheringByteChannel out, int length) throws IOException { + return wrapped.getBytes(index, out, length); + } + + @Override + public CompositeByteBuf getBytes(int index, OutputStream out, int length) throws IOException { + wrapped.getBytes(index, out, length); + return this; + } + + @Override + public CompositeByteBuf setByte(int index, int value) { + wrapped.setByte(index, value); + return this; + } + + @Override + protected final void _setByte(int index, int value) { + wrapped._setByte(index, value); + } + + @Override + public CompositeByteBuf setShort(int index, int value) { + wrapped.setShort(index, value); + return this; + } + + @Override + protected final void _setShort(int index, int value) { + wrapped._setShort(index, value); + } + + @Override + public CompositeByteBuf setMedium(int index, int value) { + wrapped.setMedium(index, value); + return this; + } + + @Override + protected final void _setMedium(int index, int value) { + wrapped._setMedium(index, value); + } + + @Override + public CompositeByteBuf setInt(int index, int value) { + wrapped.setInt(index, value); + return this; + } + + @Override + protected final void _setInt(int index, int value) { + wrapped._setInt(index, value); + } + + @Override + public CompositeByteBuf setLong(int index, long value) { + wrapped.setLong(index, value); + return this; + } + + @Override + protected final void _setLong(int index, long value) { + wrapped._setLong(index, value); + } + + @Override + public CompositeByteBuf setBytes(int index, byte[] src, int srcIndex, int length) { + wrapped.setBytes(index, src, srcIndex, length); + return this; + } + + @Override + public CompositeByteBuf setBytes(int index, ByteBuffer src) { + wrapped.setBytes(index, src); + return this; + } + + @Override + public CompositeByteBuf setBytes(int index, ByteBuf src, int srcIndex, int length) { + wrapped.setBytes(index, src, srcIndex, length); + return this; + } + + @Override + public int setBytes(int index, InputStream in, int length) throws IOException { + return wrapped.setBytes(index, in, length); + } + + @Override + public int setBytes(int index, ScatteringByteChannel in, int length) throws IOException { + return wrapped.setBytes(index, in, length); + } + + @Override + public ByteBuf copy(int index, int length) { + return wrapped.copy(index, length); + } + + @Override + public final ByteBuf component(int cIndex) { + return wrapped.component(cIndex); + } + + @Override + public final ByteBuf componentAtOffset(int offset) { + return wrapped.componentAtOffset(offset); + } + + @Override + public final ByteBuf internalComponent(int cIndex) { + return wrapped.internalComponent(cIndex); + } + + @Override + public final ByteBuf internalComponentAtOffset(int offset) { + return wrapped.internalComponentAtOffset(offset); + } + + @Override + public int nioBufferCount() { + return wrapped.nioBufferCount(); + } + + @Override + public ByteBuffer internalNioBuffer(int index, int length) { + return wrapped.internalNioBuffer(index, length); + } + + @Override + public ByteBuffer nioBuffer(int index, int length) { + return wrapped.nioBuffer(index, length); + } + + @Override + public ByteBuffer[] nioBuffers(int index, int length) { + return wrapped.nioBuffers(index, length); + } + + @Override + public CompositeByteBuf consolidate() { + wrapped.consolidate(); + return this; + } + + @Override + public CompositeByteBuf consolidate(int cIndex, int numComponents) { + wrapped.consolidate(cIndex, numComponents); + return this; + } + + @Override + public CompositeByteBuf discardReadComponents() { + wrapped.discardReadComponents(); + return this; + } + + @Override + public CompositeByteBuf discardReadBytes() { + wrapped.discardReadBytes(); + return this; + } + + @Override + public final String toString() { + return wrapped.toString(); + } + + @Override + public final CompositeByteBuf readerIndex(int readerIndex) { + wrapped.readerIndex(readerIndex); + return this; + } + + @Override + public final CompositeByteBuf writerIndex(int writerIndex) { + wrapped.writerIndex(writerIndex); + return this; + } + + @Override + public final CompositeByteBuf setIndex(int readerIndex, int writerIndex) { + wrapped.setIndex(readerIndex, writerIndex); + return this; + } + + @Override + public final CompositeByteBuf clear() { + wrapped.clear(); + return this; + } + + @Override + public final CompositeByteBuf markReaderIndex() { + wrapped.markReaderIndex(); + return this; + } + + @Override + public final CompositeByteBuf resetReaderIndex() { + wrapped.resetReaderIndex(); + return this; + } + + @Override + public final CompositeByteBuf markWriterIndex() { + wrapped.markWriterIndex(); + return this; + } + + @Override + public final CompositeByteBuf resetWriterIndex() { + wrapped.resetWriterIndex(); + return this; + } + + @Override + public CompositeByteBuf ensureWritable(int minWritableBytes) { + wrapped.ensureWritable(minWritableBytes); + return this; + } + + @Override + public CompositeByteBuf getBytes(int index, ByteBuf dst) { + wrapped.getBytes(index, dst); + return this; + } + + @Override + public CompositeByteBuf getBytes(int index, ByteBuf dst, int length) { + wrapped.getBytes(index, dst, length); + return this; + } + + @Override + public CompositeByteBuf getBytes(int index, byte[] dst) { + wrapped.getBytes(index, dst); + return this; + } + + @Override + public CompositeByteBuf setBoolean(int index, boolean value) { + wrapped.setBoolean(index, value); + return this; + } + + @Override + public CompositeByteBuf setChar(int index, int value) { + wrapped.setChar(index, value); + return this; + } + + @Override + public CompositeByteBuf setFloat(int index, float value) { + wrapped.setFloat(index, value); + return this; + } + + @Override + public CompositeByteBuf setDouble(int index, double value) { + wrapped.setDouble(index, value); + return this; + } + + @Override + public CompositeByteBuf setBytes(int index, ByteBuf src) { + wrapped.setBytes(index, src); + return this; + } + + @Override + public CompositeByteBuf setBytes(int index, ByteBuf src, int length) { + wrapped.setBytes(index, src, length); + return this; + } + + @Override + public CompositeByteBuf setBytes(int index, byte[] src) { + wrapped.setBytes(index, src); + return this; + } + + @Override + public CompositeByteBuf setZero(int index, int length) { + wrapped.setZero(index, length); + return this; + } + + @Override + public CompositeByteBuf readBytes(ByteBuf dst) { + wrapped.readBytes(dst); + return this; + } + + @Override + public CompositeByteBuf readBytes(ByteBuf dst, int length) { + wrapped.readBytes(dst, length); + return this; + } + + @Override + public CompositeByteBuf readBytes(ByteBuf dst, int dstIndex, int length) { + wrapped.readBytes(dst, dstIndex, length); + return this; + } + + @Override + public CompositeByteBuf readBytes(byte[] dst) { + wrapped.readBytes(dst); + return this; + } + + @Override + public CompositeByteBuf readBytes(byte[] dst, int dstIndex, int length) { + wrapped.readBytes(dst, dstIndex, length); + return this; + } + + @Override + public CompositeByteBuf readBytes(ByteBuffer dst) { + wrapped.readBytes(dst); + return this; + } + + @Override + public CompositeByteBuf readBytes(OutputStream out, int length) throws IOException { + wrapped.readBytes(out, length); + return this; + } + + @Override + public CompositeByteBuf skipBytes(int length) { + wrapped.skipBytes(length); + return this; + } + + @Override + public CompositeByteBuf writeBoolean(boolean value) { + wrapped.writeBoolean(value); + return this; + } + + @Override + public CompositeByteBuf writeByte(int value) { + wrapped.writeByte(value); + return this; + } + + @Override + public CompositeByteBuf writeShort(int value) { + wrapped.writeShort(value); + return this; + } + + @Override + public CompositeByteBuf writeMedium(int value) { + wrapped.writeMedium(value); + return this; + } + + @Override + public CompositeByteBuf writeInt(int value) { + wrapped.writeInt(value); + return this; + } + + @Override + public CompositeByteBuf writeLong(long value) { + wrapped.writeLong(value); + return this; + } + + @Override + public CompositeByteBuf writeChar(int value) { + wrapped.writeChar(value); + return this; + } + + @Override + public CompositeByteBuf writeFloat(float value) { + wrapped.writeFloat(value); + return this; + } + + @Override + public CompositeByteBuf writeDouble(double value) { + wrapped.writeDouble(value); + return this; + } + + @Override + public CompositeByteBuf writeBytes(ByteBuf src) { + wrapped.writeBytes(src); + return this; + } + + @Override + public CompositeByteBuf writeBytes(ByteBuf src, int length) { + wrapped.writeBytes(src, length); + return this; + } + + @Override + public CompositeByteBuf writeBytes(ByteBuf src, int srcIndex, int length) { + wrapped.writeBytes(src, srcIndex, length); + return this; + } + + @Override + public CompositeByteBuf writeBytes(byte[] src) { + wrapped.writeBytes(src); + return this; + } + + @Override + public CompositeByteBuf writeBytes(byte[] src, int srcIndex, int length) { + wrapped.writeBytes(src, srcIndex, length); + return this; + } + + @Override + public CompositeByteBuf writeBytes(ByteBuffer src) { + wrapped.writeBytes(src); + return this; + } + + @Override + public CompositeByteBuf writeZero(int length) { + wrapped.writeZero(length); + return this; + } + + @Override + public CompositeByteBuf retain(int increment) { + wrapped.retain(increment); + return this; + } + + @Override + public CompositeByteBuf retain() { + wrapped.retain(); + return this; + } + + @Override + public ByteBuffer[] nioBuffers() { + return wrapped.nioBuffers(); + } + + @Override + public CompositeByteBuf discardSomeReadBytes() { + wrapped.discardSomeReadBytes(); + return this; + } + + @Override + public final void deallocate() { + wrapped.deallocate(); + } + + @Override + public final ByteBuf unwrap() { + return wrapped; + } +}