[#3967] Guard against NPE in PendingWriteQueue

Motivation:

If the Channel is already closed when the PendingWriteQueue is created it will generate a NPE when add or remove is called later.

Modifications:

Add null checks to guard against NPE.

Result:

No more NPE possible.
This commit is contained in:
Norman Maurer 2015-07-09 22:48:10 +02:00
parent ef195348b5
commit 1be2173596
2 changed files with 27 additions and 2 deletions

View File

@ -87,8 +87,13 @@ public final class PendingWriteQueue {
tail = write;
}
size ++;
// We need to guard against null as channel.unsafe().outboundBuffer() may returned null
// if the channel was already closed when constructing the PendingWriteQueue.
// See https://github.com/netty/netty/issues/3967
if (buffer != null) {
buffer.incrementPendingOutboundBytes(write.size);
}
}
/**
* Remove all pending write operation and fail them with the given {@link Throwable}. The message will be released
@ -245,8 +250,13 @@ public final class PendingWriteQueue {
}
write.recycle();
// We need to guard against null as channel.unsafe().outboundBuffer() may returned null
// if the channel was already closed when constructing the PendingWriteQueue.
// See https://github.com/netty/netty/issues/3967
if (buffer != null) {
buffer.decrementPendingOutboundBytes(writeSize);
}
}
private static void safeFail(ChannelPromise promise, Throwable cause) {
if (!(promise instanceof VoidChannelPromise) && !promise.tryFailure(cause)) {

View File

@ -245,6 +245,21 @@ public class PendingWriteQueueTest {
assertNull(channel.readInbound());
}
// See https://github.com/netty/netty/issues/3967
@Test
public void testCloseChannelOnCreation() {
EmbeddedChannel channel = new EmbeddedChannel();
channel.close().syncUninterruptibly();
final PendingWriteQueue queue = new PendingWriteQueue(channel.pipeline().firstContext());
IllegalStateException ex = new IllegalStateException();
ChannelPromise promise = channel.newPromise();
queue.add(1L, promise);
queue.removeAndFailAll(ex);
assertSame(ex, promise.cause());
}
private static class TestHandler extends ChannelDuplexHandler {
protected PendingWriteQueue queue;
private int expectedSize;