EPollPoller Class
源码阅读
如有问题,欢迎交流
EPollPoller Class
是以Poller Class
为基类,基于epoll(4)
封装
I
/
O
多
路
复
用
I/O多路复用
I/O多路复用的具体类。
数据成员
EventLoop* ownerLoop_
本实例所在的
EventLoop
,继承自基类
std::map<int,Channel*> channels_
本实例所监视的文件描述符,继承自基类
kInitEventListSize = 16
用于初始化触发事件数组
events_
,16不大,但会根据触发情况动态增大数组大小
std::vector<struct epoll_event> events_
触发事件数组
int kNew=-1,kAdded=1,kDeleted = 2;
可见
EPollPoller Class
不像PollPoller Class
那样维护一个数组来存放其监视的文件描述符,也就不会设置Channel::index
为数组下标。EPollPoller Class
通过设置Channel Class::index
为上述三值中的某一个来确定当前Channel
是否有被监视。
函数成员
EPollPoller(EventLoop* loop)
构造函数,在初始化
ownerLoop_
的同时,还要初始化epoll
的描述符和events_
Timestamp poll(int timeoutMs, ChannelList* activeChannels)
封装基于
epoll(4)
的多路复用功能,触发事件保存到activeChannels
中(fillActiveChannels
)。
如果触发事件的数量等于events_
的数组大小了,就扩大events_
数组大小一倍。
void fillActiveChannels(int numEvents,ChannelList* activeChannels) const;
根据
numEvents
,遍历events_
,将其中的响应事件保存到activeChannels
中。并设置对应Channel
的revent
。
void updateChannel(Channel* channel)
根据
Channel::index
和Channel::isNoneEvent()
决定对epoll的文件描述符列表执行添加/删除/更新操作。
即如果index
为kNew
orkDeleted
,则添加
不然,如果isNoneEvent()==true
,则删除
如果都不是,就修改
void removeChannel(Channel* channel)
移除对
channel
的监视。
该函数与updateChannel
执行删除的区别是,本函数会删除channels_
中对应channel
的表项,而后者只是删除epoll的文件描述符列表的对应项。