diff --git a/transport/src/main/java/io/netty/channel/AbstractChannelHandlerContext.java b/transport/src/main/java/io/netty/channel/AbstractChannelHandlerContext.java index 7c68b50704..1ba26fc44c 100644 --- a/transport/src/main/java/io/netty/channel/AbstractChannelHandlerContext.java +++ b/transport/src/main/java/io/netty/channel/AbstractChannelHandlerContext.java @@ -555,6 +555,11 @@ abstract class AbstractChannelHandlerContext implements ChannelHandlerContext, R @Override public ChannelFuture disconnect(final ChannelPromise promise) { + if (!channel().metadata().hasDisconnect()) { + // Translate disconnect to close if the channel has no notion of disconnect-reconnect. + // So far, UDP/IP is the only transport that has such behavior. + return close(promise); + } if (isNotValidPromise(promise, false)) { // cancelled return promise; @@ -563,22 +568,12 @@ abstract class AbstractChannelHandlerContext implements ChannelHandlerContext, R final AbstractChannelHandlerContext next = findContextOutbound(MASK_DISCONNECT); EventExecutor executor = next.executor(); if (executor.inEventLoop()) { - // Translate disconnect to close if the channel has no notion of disconnect-reconnect. - // So far, UDP/IP is the only transport that has such behavior. - if (!channel().metadata().hasDisconnect()) { - next.invokeClose(promise); - } else { - next.invokeDisconnect(promise); - } + next.invokeDisconnect(promise); } else { safeExecute(executor, new Runnable() { @Override public void run() { - if (!channel().metadata().hasDisconnect()) { - next.invokeClose(promise); - } else { - next.invokeDisconnect(promise); - } + next.invokeDisconnect(promise); } }, promise, null); } diff --git a/transport/src/test/java/io/netty/channel/embedded/EmbeddedChannelTest.java b/transport/src/test/java/io/netty/channel/embedded/EmbeddedChannelTest.java index a5dae45afa..7c715ef13a 100644 --- a/transport/src/test/java/io/netty/channel/embedded/EmbeddedChannelTest.java +++ b/transport/src/test/java/io/netty/channel/embedded/EmbeddedChannelTest.java @@ -281,6 +281,17 @@ public class EmbeddedChannelTest { assertNull(handler.pollEvent()); } + @Test + public void testHasNoDisconnectSkipDisconnect() throws InterruptedException { + EmbeddedChannel channel = new EmbeddedChannel(false, new ChannelOutboundHandlerAdapter() { + @Override + public void close(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception { + promise.tryFailure(new Throwable()); + } + }); + assertFalse(channel.disconnect().isSuccess()); + } + @Test public void testFinishAndReleaseAll() { ByteBuf in = Unpooled.buffer();