绑定端口并向Selector注册accept事件 5
- UID
- 1066743
|
绑定端口并向Selector注册accept事件 5
通过分析readIfIsAutoRead()我们发现,调用了通道的read方法,一样的操作,最终回到了头部HeadContext#read()
private void readIfIsAutoRead() {
//该配置项默认值是1,默认条件成立
if (channel.config().isAutoRead()) {
channel.read();
}
}
@Override
public Channel read() {
//调用pipeline的read()
pipeline.read();
return this;
}
@Override
public final ChannelPipeline read() {
//从尾部开始
tail.read();
return this;
}
@Override
public ChannelHandlerContext read() {
//查找最近的一个ContextOutbound
final AbstractChannelHandlerContext next = findContextOutbound();
EventExecutor executor = next.executor();
if (executor.inEventLoop()) {
next.invokeRead();
} else {
Runnable task = next.invokeReadTask;
if (task == null) {
next.invokeReadTask = task = new Runnable() {
@Override
public void run() {
next.invokeRead();
}
};
}
executor.execute(task);
}
return this;
}
private void invokeRead() {
if (invokeHandler()) {
try {
//调用实际上是调用 ChannelHandlerContext.read方法,回到上一个方法,知道找到头部HeadContext
((ChannelOutboundHandler) handler()).read(this);
} catch (Throwable t) {
notifyHandlerException(t);
}
} else {
read();
}
}
@Override
public void read(ChannelHandlerContext ctx) {
unsafe.beginRead();
}
结合之前对unsafe实例的分析,最终进入AbstractNioChannel#doBeginRead()方法,
@Override
protected void doBeginRead() throws Exception {
//获取selectionKey
final SelectionKey selectionKey = this.selectionKey;
if (!selectionKey.isValid()) {
return;
}
readPending = true;
//改变Selector事件为OP_ACCEPT
final int interestOps = selectionKey.interestOps();
if ((interestOps & readInterestOp) == 0) {
selectionKey.interestOps(interestOps | readInterestOp);
}
}
分析一下,还记得selectionKey是什么时候初始化的吗,是在Selector注册的时候,可以翻看之前的文章。AbstractNioChannel#doRegister()中有以下代码,这个0则是SelectionKeyImpl的成员变量interestOps
selectionKey = javaChannel().register(eventLoop().unwrappedSelector(), 0, this);
而成员变量readInterestOp前面已经分析过了,构造方法初始化通道的时候,给入了OP_ACCEPT值。也就是accept事件。 |
|
|
|
|
|