Http2MultiplexCodec.DefaultHttpStreamChannel.isOpen() / isActive() shoule be false when fireChannelActive() is called

Motivation:

When part of a HTTP/2 StreamChannel the Http2StreamChannel.isOpen() / isActive() should report false within a call to a ChannelInboundHandlers channelInactive() method.

Modifications:

Fullfill promise before call fireChannelInactive()

Result:

Correctly update state / promise before notify handlers. Fixes [#7638]
This commit is contained in:
Norman Maurer 2018-01-27 02:34:37 +01:00 committed by Scott Mitchell
parent bed74d8380
commit 49d1db4113
2 changed files with 30 additions and 2 deletions

View File

@ -886,12 +886,14 @@ public class Http2MultiplexCodec extends Http2FrameCodec {
}
}
// The promise should be notified before we call fireChannelInactive().
promise.setSuccess();
closePromise.setSuccess();
pipeline().fireChannelInactive();
if (isRegistered()) {
deregister(unsafe().voidPromise());
}
promise.setSuccess();
closePromise.setSuccess();
} finally {
pendingClosePromise = null;
}

View File

@ -31,6 +31,7 @@ import io.netty.util.AsciiString;
import io.netty.util.AttributeKey;
import java.net.InetSocketAddress;
import java.util.concurrent.atomic.AtomicBoolean;
import org.junit.After;
import org.junit.Before;
@ -420,6 +421,31 @@ public class Http2MultiplexCodecTest {
assertEquals("true,false", inboundHandler.writabilityStates());
}
@Test
public void channelClosedWhenInactiveFired() {
LastInboundHandler inboundHandler = streamActiveAndWriteHeaders(inboundStream);
Http2StreamChannel childChannel = (Http2StreamChannel) inboundHandler.channel();
final AtomicBoolean channelOpen = new AtomicBoolean(false);
final AtomicBoolean channelActive = new AtomicBoolean(false);
assertTrue(childChannel.isOpen());
assertTrue(childChannel.isActive());
childChannel.pipeline().addLast(new ChannelInboundHandlerAdapter() {
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
channelOpen.set(ctx.channel().isOpen());
channelActive.set(ctx.channel().isActive());
super.channelInactive(ctx);
}
});
childChannel.close().syncUninterruptibly();
assertFalse(channelOpen.get());
assertFalse(channelActive.get());
}
@Ignore("not supported anymore atm")
@Test
public void cancellingWritesBeforeFlush() {