diff --git a/transport/src/main/java/io/netty/channel/local/LocalServerChannel.java b/transport/src/main/java/io/netty/channel/local/LocalServerChannel.java index 73647c8ac2..f798e56e05 100644 --- a/transport/src/main/java/io/netty/channel/local/LocalServerChannel.java +++ b/transport/src/main/java/io/netty/channel/local/LocalServerChannel.java @@ -96,8 +96,10 @@ public class LocalServerChannel extends AbstractServerChannel { protected void doClose() throws Exception { if (state <= 1) { // Update all internal state before the closeFuture is notified. - LocalChannelRegistry.unregister(localAddress); - localAddress = null; + if (localAddress != null) { + LocalChannelRegistry.unregister(localAddress); + localAddress = null; + } state = 2; } } diff --git a/transport/src/test/java/io/netty/bootstrap/BootstrapTest.java b/transport/src/test/java/io/netty/bootstrap/BootstrapTest.java index 8d2a3a23cd..1a09cc2ff3 100644 --- a/transport/src/test/java/io/netty/bootstrap/BootstrapTest.java +++ b/transport/src/test/java/io/netty/bootstrap/BootstrapTest.java @@ -27,7 +27,6 @@ import io.netty.channel.ChannelPromise; import io.netty.channel.EventLoopGroup; import io.netty.channel.local.LocalAddress; import io.netty.channel.local.LocalChannel; -import io.netty.channel.local.LocalEventLoopGroup; import io.netty.channel.local.LocalServerChannel; import io.netty.util.concurrent.Future; import org.junit.Assert; @@ -162,6 +161,32 @@ public class BootstrapTest { } } + @Test + public void testLateRegisterFailed() throws Exception { + final TestEventLoopGroup group = new TestEventLoopGroup(); + try { + ServerBootstrap bootstrap = new ServerBootstrap(); + bootstrap.group(group); + bootstrap.channel(LocalServerChannel.class); + bootstrap.childHandler(new DummyHandler()); + bootstrap.localAddress(new LocalAddress("1")); + ChannelFuture future = bootstrap.bind(); + Assert.assertFalse(future.isDone()); + group.promise.setFailure(new IllegalStateException()); + final BlockingQueue queue = new LinkedBlockingQueue(); + future.addListener(new ChannelFutureListener() { + @Override + public void operationComplete(ChannelFuture future) throws Exception { + queue.add(group.next().inEventLoop(Thread.currentThread())); + } + }); + Assert.assertFalse(queue.take()); + } finally { + group.shutdownGracefully(); + group.terminationFuture().sync(); + } + } + private static final class TestEventLoopGroup extends DefaultEventLoopGroup { ChannelPromise promise; TestEventLoopGroup() {