NOTE

3. Register the Selector

Call path and event-loop registration

JavaCreated Updated 1 min readhistorical

This is a historical learning note and may contain outdated or incomplete understanding.

Call Path

bind

  • doBind
  • initAndRegister
    • channelFactory.newChannel()
    • init(channel)
    • ChannelFuture regFuture = config().group().register(channel); — this is the part to focus on.

Set a breakpoint on register. The final call stack is:

io.netty.channel.MultithreadEventLoopGroup#register(io.netty.channel.Channel)

io.netty.channel.SingleThreadEventLoop#register(io.netty.channel.Channel)

io.netty.channel.SingleThreadEventLoop#register(io.netty.channel.ChannelPromise)

io.netty.channel.AbstractChannel.AbstractUnsafe#register

public final void register(EventLoop eventLoop, final ChannelPromise promise) {
    if (eventLoop == null) {
        throw new NullPointerException("eventLoop");
    }
    if (isRegistered()) {
        promise.setFailure(new IllegalStateException("registered to an event loop already"));
        return;
    }
    if (!isCompatible(eventLoop)) {
        promise.setFailure(
                new IllegalStateException("incompatible event loop type: " + eventLoop.getClass().getName()));
        return;
    }
    // Associate the eventLoop with this channel.
    // All subsequent channel operations go through this eventLoop.
    AbstractChannel.this.eventLoop = eventLoop;

    if (eventLoop.inEventLoop()) {
        register0(promise);// actual registration
    } else {
        try {
            eventLoop.execute(new Runnable() {
                @Override
                public void run() {
                    register0(promise);
                }
            });
        } catch (Throwable t) {
            logger.warn(
                    "Force-closing a channel whose registration task was not accepted by an event loop: {}",
                    AbstractChannel.this, t);
            closeForcibly();
            closeFuture.setClosed();
            safeSetFailure(promise, t);
        }
    }
}
  • register0
doRegister();// call the low-level JDK registration: io.netty.channel.nio.AbstractNioChannel#doRegister

pipeline.invokeHandlerAddedIfNeeded();

// call channelRegistered on the ChannelHandler
pipeline.fireChannelRegistered();

Discussion

Sign in with GitHub to comment. Discussions are stored as GitHub Issues.View on GitHub