一 注册selector大纲
1. AbstractChannel.register(channel) //入口
2. this.eventLoop = eventLoop //绑定线程
3. register0() //实际注册
4.register0()调用流程
doRegister() //调用jdk底层的注册方法
fireChannelRegistered() //调用传播事件
二 注册selector流程
@Override public final void register(EventLoop eventLoop, final ChannelPromise promise) { if (eventLoop == null) { throw new NullPointerException("eventLoop"); } if (promise == null) { throw new NullPointerException("promise"); } 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; } // 1. 添加eventLoop if (AbstractChannel.this.eventLoop == null) { AbstractChannel.this.eventLoop = new PausableChannelEventLoop(eventLoop); } else { AbstractChannel.this.eventLoop.unwrapped = eventLoop; } if (eventLoop.inEventLoop()) { //2. 调用实际的注册方法 register0(promise); } else { try { eventLoop.execute(new OneTimeTask() { @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); } } }
private void register0(ChannelPromise promise) { try { // check if the channel is still open as it could be closed in the mean time when the register // call was outside of the eventLoop if (!promise.setUncancellable() || !ensureOpen(promise)) { return; } boolean firstRegistration = neverRegistered; //1.调用jdk底层的注册方法 doRegister(); neverRegistered = false; registered = true; eventLoop.acceptNewTasks(); safeSetSuccess(promise); //2. 传播事件 pipeline.fireChannelRegistered(); // Only fire a channelActive if the channel has never been registered. This prevents firing // multiple channel actives if the channel is deregistered and re-registered. if (firstRegistration && isActive()) { pipeline.fireChannelActive(); } } catch (Throwable t) { // Close the channel directly to avoid FD leak. closeForcibly(); closeFuture.setClosed(); safeSetFailure(promise, t); } }
@Override protected void doRegister() throws Exception { boolean selected = false; for (;;) { try { //调用jdk底层的register方法注册 selectionKey = javaChannel().register(((NioEventLoop) eventLoop().unwrap()).selector, 0, this); return; } catch (CancelledKeyException e) { if (!selected) { // Force the Selector to select now as the "canceled" SelectionKey may still be // cached and not removed because no Select.select(..) operation was called yet. ((NioEventLoop) eventLoop().unwrap()).selectNow(); selected = true; } else { // We forced a select operation on the selector before but the SelectionKey is still cached // for whatever reason. JDK bug ? throw e; } } } }