PollPoller Class
详解/源码阅读(muduo/net/poller
)
@(如有问题欢迎交流)
PollPoller Class
是基于poll(2)
的
I
/
O
复
用
I/O复用
I/O复用具体类,以Poller Class
为基类。
数据成员
EventLoop* ownerLoop_
继承于基类,通过构造函数初始化
std::map<int, Channel*> channels_
继承于基类
std::vector<struct pollfd> pollfds_
基于
Channel
初始化的pollfd
类型的容器
函数成员
PollPoller
构造函数,只负责初始化
ownerLoop_
Timestamp poll(int timeoutMs, ChannelList* activeChannels)
1 调用
poll
监听就绪事件
2 将就绪事件填入activeChannels
(fillActiveChannels
)
void fillActiveChannels(int numEvents,ChannelList* activeChannels) const;
遍历
pollfds_
,将就绪事件的Channel
填入activeChannels
1 对于pollfds_
中的每一项检查pollfd::revents
是否大于0
2 如果满足pollfd::revents
大于0,就根据pollfd::fd
在channels_
中寻找Channel
。并将其填入activeChannels
void updateChannel(Channel* channel)
添加or更新channel
1 如果是添加(channel::index<0
)
2 首先检查channel
不存在于channels_
中
3 为channel创建pollfd
数据,并保存到pollfds_
中
4 设置channel
的idx
为其在pollfds_
中的下标
5 最后将channel
保存到channels_
中
1 如果是更新
2 首先检查channel
是否存在于channels_
中
3 检查Channel::idx
是否有效
4 检查文件描述符是否有效
5 修改监视事件
6 如果暂时不关心监视的事件,就修改pollfds_
对应项的文件描述符
void removeChannel(Channel* channel)
移除
channel
1 移除时,需要确认channel
不再关心监视的事件(Channel::isNoneEvent==true
)
2 从channels_
中剔除channel
3 如果channel
是最后一个,则直接从pollfds_
中剔除
4 如果不是,则交换最后一个和channel