WebServer----Epoll类

Epoll的构造

Epoll类是事件循环EventLoop的核心结构,每一个EventLoop都持有一个Epoll分发器,因此Epoll对象的创建是在EventLoop的构造函数中完成的。

EventLoop::EventLoop()
:   looping_(false),
    poller_(new Epoll()),  ...
//通过系统调用epoll_create1创建一个epollfd_
Epoll():epollFd_(epoll_create1(EPOLL_COLEXEC)),events(EVENTSNUM){
	assert(epollFd_>0);
}

//通过getEpollFd函数将可以得到该Epollfd_
int getEpollFd();

Epoll的数据成员

    static const int MAXFDS = 100000;
    int epollFd_;
    std::vector<epoll_event> events_;   //用于存储将要回传的事件列表
    std::shared_ptr<Channel> fd2chan_[MAXFDS];   //fd到Channel的映射数组
    std::shared_ptr<HttpData> fd2http_[MAXFDS];  //fd到HttpData对象的映射数组
    TimerManager timerManager_;     //定时器管理器,用于踢掉超时的连接

因为fd过于单薄,需要Channel类来将fd以及events等绑定在一起。而epoll中又是以fd为单位进行注册、修改和删除,因此需要定义 fd2chan_[MAXFDS] 这样一个映射结构,在epoll中将fd和对应的Channel连接起来。而fd2http_[MAXFDS] 是一个shared_ptr数组,主要是确保在调用channel的回调函数时,其上层持有者还未被析构。通过bind()绑定的this指针还有效。

添加、修改、删除监听事件

void epoll_add(SP_Channel request, int timeout);
void epoll_mod(SP_Channel request, int timeout);
void epoll_del(SP_Channel request);

通过系统调用epoll_ctl,传入参数 EPOLL_CTL_ADD、EPOLL_CTL_MOD、EPOLL_CTL_DEL来实行添加、修改、删除操作,其中epoll_event结构中需要的fd通过Channel的getfd()获取,events参数则通过getevents和getlastevents获取。完成操作后同时更新fd2chan_ 和 fd2http_ 数组。

epoll主体工作

epoll的主要工作是通过两个函数实现的,一个是poll、另一个是getEventsRequest;

std::vector<std::shared_ptr<Channel>> poll();
std::vector<std::shared_ptr<Channel>> getEventsRequest(int events_num);

其中poll函数会调用epoll_wait函数来阻塞等待事件的发生,epoll_wait返回之后则调用getEventsRequset设置相应Channel中Revents为相应epoll_events中的检测到的事件events。然后返回有事件产生的通道数组。

定时器相关、超时处理

void add_timer(std::shared_ptr<Channel> request_data, int timeout);
void handleExpired();

你可能感兴趣的:(server)