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 6e5ab465d9
commit b2fca0cf18
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