有没有可能在执行ServerBootstrap.bind()的时候,pipeline.fireChannelActive()执行了两次?

Is there a possibility that pipeline.fireChannelActive() is executed twice when executing ServerBootstrap.bind()?

以下代码均来自Netty4.0.31.Final。 ServerBootstrap 的频道是 NioServerSocketChannel

ServerBootstrap.bind(int)的主要逻辑在AbstractBootstrap.doBind(SocketAddress):

private ChannelFuture doBind(final SocketAddress localAddress) {
        final ChannelFuture regFuture = initAndRegister();
        ...
        if (regFuture.isDone()) {
            ...
            doBind0(regFuture, channel, localAddress, promise);
            ...
        } else {
            regFuture.addListener(new ChannelFutureListener() {
                @Override
                public void operationComplete(ChannelFuture future) throws Exception {
                    ...
                    doBind0(regFuture, channel, localAddress, promise);
                }
            });
        }
}

initAndRegister()中的代码最终进入AbstractUnsafe.register0(ChannelPromise promise):

private void register0(ChannelPromise promise) {
        try {
            ...
            boolean firstRegistration = neverRegistered;
            doRegister();
            ...
            if (firstRegistration && isActive()) {
                pipeline.fireChannelActive();
            }
        } catch (Throwable t) {
            ...
        }
 }

可以看到,pipeline.fireChannelActive()这里可能会被执行

让我们回到 AbstractBootstrap.doBind(SocketAddress),在 doBind0(regFuture, channel, localAddress, promise) 中,代码最终进入 AbstractUnsafe.bind(SocketAddress,ChannelPromise):

public final void bind(final SocketAddress localAddress, final ChannelPromise promise) {
        ...
        boolean wasActive = isActive();
        try {
            doBind(localAddress);
        } catch (Throwable t) {
            ...
        }

        if (!wasActive && isActive()) {
            invokeLater(new OneTimeTask() {
                @Override
                public void run() {
                    pipeline.fireChannelActive();
                }
            });
        }
        ...
    }

如你所见,pipeline.fireChannelActive()也可能在这里执行

那么,有没有可能在创建绑定一个NioServerSocketChannel的时候,pipeline.fireChannelActive()执行了两次?

除非 isActive 可以在您指出的流程中再次从真到假再到真。我认为它只能激活一次,所以 false -> true -> false

来自您的 post 的相关代码:

boolean firstRegistration = neverRegistered;
...
if (firstRegistration && isActive()) {
    pipeline.fireChannelActive();  // isActive must be TRUE
}
...
boolean wasActive = isActive();
...
// If fireChannelActive was fired, then wasActive would be true, 
// preventing it from firing again
if (!wasActive && isActive()) {  
    invokeLater(new OneTimeTask() {
        @Override
        public void run() {
            pipeline.fireChannelActive();