[#2400] Not close LocalChannel during deregister() to allow register to other EventLoop
Motivation: At the moment it is not possible to deregister a LocalChannel from its EventLoop and register it to another one as the LocalChannel is closed during the deregister. Modification: Not close the LocalChannel during dergister Result: It is now possible to deregister a LocalChannel and register it to another EventLoop
This commit is contained in:
parent
b5ab5150be
commit
7ae40ace32
@ -155,7 +155,12 @@ public class LocalChannel extends AbstractChannel {
|
||||
|
||||
@Override
|
||||
protected void doRegister() throws Exception {
|
||||
if (peer != null) {
|
||||
// Check if both peer and parent are non-null because this channel was created by a LocalServerChannel.
|
||||
// This is needed as a peer may not be null also if a LocalChannel was connected before and
|
||||
// deregistered / registered later again.
|
||||
//
|
||||
// See https://github.com/netty/netty/issues/2400
|
||||
if (peer != null && parent() != null) {
|
||||
// Store the peer in a local variable as it may be set to null if doClose() is called.
|
||||
// Because of this we also set registerInProgress to true as we check for this in doClose() and make sure
|
||||
// we delay the fireChannelInactive() to be fired after the fireChannelActive() and so keep the correct
|
||||
@ -237,9 +242,7 @@ public class LocalChannel extends AbstractChannel {
|
||||
|
||||
@Override
|
||||
protected void doDeregister() throws Exception {
|
||||
if (isOpen()) {
|
||||
unsafe().close(unsafe().voidPromise());
|
||||
}
|
||||
// Just remove the shutdownHook as this Channel may be closed later or registered to another EventLoop
|
||||
((SingleThreadEventExecutor) eventLoop()).removeShutdownHook(shutdownHook);
|
||||
}
|
||||
|
||||
|
@ -248,6 +248,39 @@ public class LocalChannelTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReRegister() {
|
||||
EventLoopGroup group1 = new LocalEventLoopGroup();
|
||||
EventLoopGroup group2 = new LocalEventLoopGroup();
|
||||
LocalAddress addr = new LocalAddress(LOCAL_ADDR_ID);
|
||||
Bootstrap cb = new Bootstrap();
|
||||
ServerBootstrap sb = new ServerBootstrap();
|
||||
|
||||
cb.group(group1)
|
||||
.channel(LocalChannel.class)
|
||||
.handler(new TestHandler());
|
||||
|
||||
sb.group(group2)
|
||||
.channel(LocalServerChannel.class)
|
||||
.childHandler(new ChannelInitializer<LocalChannel>() {
|
||||
@Override
|
||||
public void initChannel(LocalChannel ch) throws Exception {
|
||||
ch.pipeline().addLast(new TestHandler());
|
||||
}
|
||||
});
|
||||
|
||||
// Start server
|
||||
final Channel sc = sb.bind(addr).syncUninterruptibly().channel();
|
||||
|
||||
// Connect to the server
|
||||
final Channel cc = cb.connect(addr).syncUninterruptibly().channel();
|
||||
|
||||
cc.deregister().syncUninterruptibly();
|
||||
// Change event loop group.
|
||||
group2.register(cc).syncUninterruptibly();
|
||||
cc.close().syncUninterruptibly();
|
||||
sc.close().syncUninterruptibly();
|
||||
}
|
||||
static class TestHandler extends ChannelInboundHandlerAdapter {
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
|
||||
|
Loading…
Reference in New Issue
Block a user