NOTE
3. Register the Selector
Call path and event-loop registration
This is a historical learning note and may contain outdated or incomplete understanding.
Call Path
bind
doBindinitAndRegisterchannelFactory.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