Always return SliceByteBuf on slice(...) to eliminate possible leak

Motivation:

When calling slice(...) on a ByteBuf the returned ByteBuf should be the slice of a ByteBuf and shares it's reference count. This is important as it is perfect legal to use buf.slice(...).release() and have both, the slice and the original ByteBuf released. At the moment this is only the case if the requested slice size is > 0. This makes the behavior inconsistent and so may lead to a memory leak.

Modifications:

- Never return Unpooled.EMPTY_BUFFER when calling slice(...).
- Adding test case for buffer.slice(...).release() and buffer.duplicate(...).release()

Result:

Consistent behaviour and so no more leaks possible.
This commit is contained in:
Norman Maurer 2014-12-11 20:50:54 +01:00 committed by Norman Maurer
parent 699e6e3b02
commit a69a39c849
2 changed files with 16 additions and 4 deletions

View File

@ -903,10 +903,6 @@ public abstract class AbstractByteBuf extends ByteBuf {
@Override
public ByteBuf slice(int index, int length) {
if (length == 0) {
return Unpooled.EMPTY_BUFFER;
}
return new SlicedByteBuf(this, index, length);
}

View File

@ -2456,6 +2456,22 @@ public abstract class AbstractByteBufTest {
}
}
@Test
public void testSliceRelease() {
ByteBuf buf = newBuffer(8);
assertEquals(1, buf.refCnt());
assertTrue(buf.slice().release());
assertEquals(0, buf.refCnt());
}
@Test
public void testDuplicateRelease() {
ByteBuf buf = newBuffer(8);
assertEquals(1, buf.refCnt());
assertTrue(buf.duplicate().release());
assertEquals(0, buf.refCnt());
}
// Test-case trying to reproduce:
// https://github.com/netty/netty/issues/2843
@Test