epoller.h
#ifndef EPOLLER_H_
#define EPOLLER_H_
#include <sys/epoll.h> //epoll_ctl()
#include <fcntl.h> //fcntl()
#include <unistd.h> //close()
#include <vector>
#include <errno.h>
class Epoller{
public:
explicit Epoller(int maxEvent =1024);
~Epoller();
// 核心操作:添加、修改、删除文件描述符及其事件
bool AddFd(int fd,uint32_t events);
bool ModFd(int fd,uint32_t events);
bool DelFd(int fd);
// 等待事件就绪
int Wait(int timeoutMs=-1);
// 获取就绪事件的文件描述符和事件类型
int GetEventFd(size_t i) const;
uint32_t GetEvents(size_t i) const;
private:
int epollFd_; // epoll实例的文件描述符
std::vector<struct epoll_event> events_;// 存储就绪事件的数组
};
#endif
epoller.cpp
#include "epoller.h"
// 创建epoll对象 epoll_create(512)
Epoller::Epoller(int maxEvent):epollFd_(epoll_create(512)), events_(maxEvent){
assert(epollFd_ >= 0 && events_.size() > 0);
}
Epoller::~Epoller() {
close(epollFd_);
}
// 添加文件描述符到epoll中进行管理
bool Epoller::AddFd(int fd, uint32_t events) {
if(fd < 0) return false;
epoll_event ev = {0};
ev.data.fd = fd;
ev.events = events;
return 0 == epoll_ctl(epollFd_, EPOLL_CTL_ADD, fd, &ev);
}
// 修改
bool Epoller::ModFd(int fd, uint32_t events) {
if(fd < 0) return false;
epoll_event ev = {0};
ev.data.fd = fd;
ev.events = events;
return 0 == epoll_ctl(epollFd_, EPOLL_CTL_MOD, fd, &ev); // 此时修改了事件的模式如EPOLLOUT
}
// 删除
bool Epoller::DelFd(int fd) {
if(fd < 0) return false;
epoll_event ev = {0};
return 0 == epoll_ctl(epollFd_, EPOLL_CTL_DEL, fd, &ev);
}
// 调用epoll_wait()进行事件检测
int Epoller::Wait(int timeoutMs) {
return epoll_wait(epollFd_, &events_[0], static_cast<int>(events_.size()), timeoutMs); // events == &events[0]
}
// 获取产生事件的文件描述符
int Epoller::GetEventFd(size_t i) const {
assert(i < events_.size() && i >= 0);
return events_[i].data.fd;
}
// 获取事件
uint32_t Epoller::GetEvents(size_t i) const {
assert(i < events_.size() && i >= 0);
return events_[i].events;
}