目录
类功能
类设计
类实现
编译
类功能
类设计
//Poller描述符监控类
#define MAX_EPOLLEVENTS
class Poller{private:int _epfd;struct epoll_event _evs[MAX_EPOLLEVENTS];std::unordered_map<int, Channel *> _channels;private:// 对epoll的直接操作void Update(Channel *channel, int op);bool HasChannel(Channel *Channel);public:Poller();// 添加或修改监控事件void UpdateEvent(Channel *channel);// 移除监控void RemoveEvent(Channel *channel);// 开始监控, 返回活跃连接void Poll(std::vector<Channel*> *active);
};
类实现
// Poller描述符监控类
#define MAX_EPOLLEVENTS 1024
class Poller
{
private:int _epfd;struct epoll_event _evs[MAX_EPOLLEVENTS];std::unordered_map<int, Channel *> _channels;private:// 对epoll的直接操作void Update(Channel *channel, int op){// int epoll_ctl(int epfd, int op, int fd, struct epoll_event *ev)int fd = channel->Fd();struct epoll_event ev;ev.data.fd = fd;ev.events = channel->Events();int ret = epoll_ctl(_epfd, op, fd, &ev);}// 判断一个Channel 是否已经添加了事件监控bool HasChannel(Channel *channel){auto it = _channels.find(channel->Fd());if (it == _channels.end()){return false;}return true;}public:Poller(){_epfd = epoll_create(MAX_EPOLLEVENTS); // 这个值大于0就行了,无用处if (_epfd < 0){ERR_LOG("EPOLL CREATE FAILED!");abort(); // 退出程序}}// 添加或修改监控事件void UpdateEvent(Channel *channel){bool ret = HasChannel(channel);if (ret == false){// 不存在则添加_channels.insert(std::make_pair(channel->Fd(), channel));return Update(channel, EPOLL_CTL_ADD);}return Update(channel, EPOLL_CTL_MOD);}// 移除监控void RemoveEvent(Channel *channel){auto it = _channels.find(channel->Fd());if (it != _channels.end()){_channels.erase(it);}Update(channel, EPOLL_CTL_DEL);}// 开始监控, 返回活跃连接void Poll(std::vector<Channel*> *active){// int epoll_wait(int epfd, struct epoll_event *evs, int maxevents, int timeout);int nfds = epoll_wait(_epfd, _evs, MAX_EPOLLEVENTS, -1); // -1阻塞监控if (nfds < 0){if (errno == EINTR) // 信号打断{return;}ERR_LOG("EPOLL WAIT ERROR:%s\n", strerror(errno));abort();}for (int i = 0; i < nfds; i++) // 添加活跃信息{auto it = _channels.find(_evs[i].data.fd); // 没找到就说明不在我们的管理之下,这是不正常的assert(it != _channels.end());it->second->SetREvents(_evs[i].events); // 设置实际就绪的事件active->push_back(it->second);}return;}
};
编译
语法编译目前没问题,Poller模块与Channel模块整合在下一节介绍