Skip to content

Commit

Permalink
[netty#1385] Fix NPE which was triggered if a write was executed but …
Browse files Browse the repository at this point in the history
…the HeadHandler not init yet
  • Loading branch information
Norman Maurer committed May 23, 2013
1 parent 1801ecf commit 9c925b1
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* Copyright 2013 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.testsuite.transport.socket;

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelStateHandlerAdapter;
import io.netty.channel.socket.SocketChannel;
import org.junit.Test;

public class WriteBeforeRegisteredTest extends AbstractClientSocketTest {

@Test(timeout = 30000)
public void testWriteBeforeConnect() throws Throwable {
run();
}

public void testWriteBeforeConnect(Bootstrap cb) throws Throwable {
TestHandler h = new TestHandler();
SocketChannel ch = null;
try {
ch = (SocketChannel) cb.handler(h).connect().channel();
ch.write(Unpooled.wrappedBuffer(new byte[] { 1 })).await();
} finally {
if (ch != null) {
ch.close();
}
}
}

private static class TestHandler extends ChannelStateHandlerAdapter {

@Override
public void inboundBufferUpdated(ChannelHandlerContext ctx) throws Exception {
ctx.fireInboundBufferUpdated();
}

@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1502,7 +1502,7 @@ public ChannelFuture write(final Object message, final ChannelPromise promise) {
validateFuture(promise, true);

DefaultChannelHandlerContext ctx = prev;
EventExecutor executor;
EventExecutor executor = executor();
final boolean msgBuf;

if (message instanceof ByteBuf) {
Expand All @@ -1519,7 +1519,26 @@ public ChannelFuture write(final Object message, final ChannelPromise promise) {
break;
}

ctx = ctx.prev;
DefaultChannelHandlerContext prev = ctx.prev;
if (prev == null) {
assert ctx == pipeline.head;
// this means we reached end of pipeline but the head-handler was not yet init.
// in this case init it now and schedule the write via the executor so it is
// done after fireChannelRegistered() completes
//
// See https://github.com/netty/netty/issues/1385
ctx.initHeadHandler();

executor.execute(new Runnable() {
@Override
public void run() {
write(message, promise);
}
});
return promise;
} else {
ctx = prev;
}
}
} else {
msgBuf = true;
Expand Down

0 comments on commit 9c925b1

Please sign in to comment.