前言
上一篇分析了Channel在启动过程中是如何初始化的,接下来我们在上一篇的代码的基础上,继续分析Channel是如何注册的
正文
继续接到上一篇中initAndRegister()方法里面的
ChannelFuture regFuture = config().group().register(channel);
// 具体注册过程1
io.netty.channel.SingleThreadEventLoop
@Override
public ChannelFuture register(Channel channel) {
return register(new DefaultChannelPromise(channel, this));
}
@Override
public ChannelFuture register(final ChannelPromise promise) {
ObjectUtil.checkNotNull(promise, "promise");
// 【重要代码】
promise.channel().unsafe().register(this, promise);
return promise;
}
// 具体注册过程2
io.netty.channel.AbstractChannel.AbstractUnsafe
@Override
public final void register(EventLoop eventLoop, final ChannelPromise promise) {
ObjectUtil.checkNotNull(eventLoop, "eventLoop");
// 检查是否已经注册过了
if (isRegistered()) {
promise.setFailure(new IllegalStateException("registered to an event loop already"));
return;
}
// 检查eventLoop的类型
if (!isCompatible(eventLoop)) {
promise.setFailure(
new IllegalStateException("incompatible event loop type: " + eventLoop.getClass().getName()));
return;
}
AbstractChannel.this.eventLoop = eventLoop;
// 判断是否在当前eventLoop里面执行(启动的时候是在主线程里面执行,不是在eventLoop里面执行)
if (eventLoop.inEventLoop()) {
// 【重要代码】最终都会调用register0()
register0(promise);
} else {
try {
// eventLoop.execute这种调用,eventLoop.inEventLoop()才会返回true,因为是通过eventLoop调用的
eventLoop.execute(new Runnable() {
@Override
public void run() {
register0(promise);
}
});
} catch (Throwable t) {
closeForcibly();
closeFuture.setClosed();
safeSetFailure(promise, t);
}
}
}
private void register0(ChannelPromise promise) {
try {
if (!promise.setUncancellable() || !ensureOpen(promise)) {
return;
}
boolean firstRegistration = neverRegistered;
// 【重要代码】
doRegister();
neverRegistered = false;
registered = true;
pipeline.invokeHandlerAddedIfNeeded();
safeSetSuccess(promise);
pipeline.fireChannelRegistered();
if (isActive()) {
if (firstRegistration) {
pipeline.fireChannelActive();
} else if (config().isAutoRead()) {
beginRead();
}
}
} catch (Throwable t) {
closeForcibly();
closeFuture.setClosed();
safeSetFailure(promise, t);
}
}
@Override
protected void doRegister() throws Exception {
boolean selected = false;
for (;;) {
try {
// 把channel注册到Selector中,到此channel的初始化和注册过程完成
// 【重要代码,后面分析】Netty优化后的Selector是如何创建的
selectionKey = javaChannel().register(eventLoop().unwrappedSelector(), 0, this);
return;
} catch (CancelledKeyException e) {
if (!selected) {
eventLoop().selectNow();
selected = true;
} else {
throw e;
}
}
}
}