[#2843] Add test-case to show correct behavior of ByteBuf.refCnt() and ByteBuf.release(...)

Motivation:

We received a bug-report that the ByteBuf.refCnt() does sometimes not show the correct value when release() and refCnt() is called from different Threads.

Modifications:

Add test-case which shows that all is working like expected

Result:

Test-case added which shows everything is ok.
This commit is contained in:
Norman Maurer 2014-09-01 08:48:15 +02:00
parent 98a533ae44
commit 4e62b51c6d

View File

@ -2430,6 +2430,62 @@ public abstract class AbstractByteBufTest {
releasedBuffer().nioBuffers(0, 1); releasedBuffer().nioBuffers(0, 1);
} }
// Test-case trying to reproduce:
// https://github.com/netty/netty/issues/2843
@Test
public void testRefCnt() throws Exception {
testRefCnt0(false);
}
// Test-case trying to reproduce:
// https://github.com/netty/netty/issues/2843
@Test
public void testRefCnt2() throws Exception {
testRefCnt0(true);
}
private void testRefCnt0(final boolean parameter) throws Exception {
for (int i = 0; i < 10; i++) {
final CountDownLatch latch = new CountDownLatch(1);
final CountDownLatch innerLatch = new CountDownLatch(1);
final ByteBuf buffer = newBuffer(4);
assertEquals(1, buffer.refCnt());
final AtomicInteger cnt = new AtomicInteger(Integer.MAX_VALUE);
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
boolean released;
if (parameter) {
released = buffer.release(buffer.refCnt());
} else {
released = buffer.release();
}
assertTrue(released);
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
cnt.set(buffer.refCnt());
latch.countDown();
}
});
t2.start();
try {
// Keep Thread alive a bit so the ThreadLocal caches are not freed
innerLatch.await();
} catch (InterruptedException ignore) {
// ignore
}
}
});
t1.start();
latch.await();
assertEquals(0, cnt.get());
innerLatch.countDown();
}
}
static final class TestGatheringByteChannel implements GatheringByteChannel { static final class TestGatheringByteChannel implements GatheringByteChannel {
private final ByteArrayOutputStream out = new ByteArrayOutputStream(); private final ByteArrayOutputStream out = new ByteArrayOutputStream();
private final WritableByteChannel channel = Channels.newChannel(out); private final WritableByteChannel channel = Channels.newChannel(out);