代码拉取完成,页面将自动刷新
/***
* @Description:
* @Author: LeoTao
* @Date: 2023-10-05 22:59:32
* @LastEditTime: 2023-10-06 23:15:18
*/
#include "EpollPoller.h"
#include "logger.h"
#include "Channel.h"
#include <errno.h>
#include <string.h>
const int kNew = -1; //channel未添加到poller中
const int kAdded = 1;//channel已经添加到poller中
const int kDeleted = 2;//channel从epoll中删除
EpollPoller::EpollPoller(EventLoop* loop)
: Poller(loop),
epollfd_(::epoll_create1(EPOLL_CLOEXEC)),
events_(kInitEventListSize)
{
if(epollfd_ < 0){
LOG_FATAL("epoll_create error : %d\n", errno);
}
}
EpollPoller::~EpollPoller() {
::close(epollfd_);
}
// 重写基类Poller的抽象方法
Timestamp EpollPoller::poll(int timeouts,
ChannelList* activeChannels) {
//使用LOG_DEBUG更适合,方便调试使用了info
LOG_INFO("func = %s => total count : %ld\n", __FUNCTION__, channels_.size());
//events_.begin() events起始的迭代器,但是迭代器底层是数组,*解引用得到数组,加&得到数组的首地址
int numEvents = ::epoll_wait(epollfd_, &*events_.begin(), static_cast<int>(events_.size()), timeouts);
//保存错误号
int saveErrno = errno;
Timestamp now(Timestamp::now());
if (numEvents > 0) { // 有事件发生
LOG_INFO("%d events happend\n", numEvents);
fillActiveChannels(numEvents, activeChannels);
// 当前监听的事件个数刚好等于事件的总数
// 需要扩容
if (numEvents == events_.size()) {
events_.resize(events_.size() * 2);
}
} else if (numEvents == 0) {
// timeout事件内没有事件发生
LOG_DEBUG("%s timeout!\n nothing happend", __function__);
} else {
// 不是被内部信号中断
if (saveErrno != EINTR) {
errno = saveErrno;
LOG_ERROR("EPollPoller::poll() err!");
}
}
return now;
}
void EpollPoller::updateChannel(Channel* channel) {
const int index = channel->index(); //获取当前channel在poller中的状态
LOG_INFO("func = %s => fd = %d, events = %d, index = %d\n", __FUNCTION__, channel->fd(), channel->events(), index);
if(index == kNew || index == kDeleted){ //channel没有注册过或者注册过被删除
int fd = channel->fd();
if (index == kNew) {
if (channels_.find(fd) != channels_.end()) {
channels_[fd] = channel;
}
// 添加成功
channel->set_index(kAdded);
update(EPOLL_CTL_ADD, channel);
}
} else {
int fd = channel->fd();
if(channel->isNoneEvent()){//channel对任何事件都不感兴趣了
update(EPOLL_CTL_DEL, channel);
channel->set_index(kDeleted);
} else {
update(EPOLL_CTL_MOD, channel);
}
}
}
void EpollPoller::removeChannel(Channel* channel){
int fd = channel->fd();
//在channelMap里面删除
channels_.erase(fd);
LOG_INFO("func = %s => fd = %d\n", __FUNCTION__, fd);
//修改状态
int index = channel->index();
if(index == kAdded){
//添加过了,需要从epoll里面删除
update(EPOLL_CTL_DEL, channel);
}
channel->set_index(kNew);
}
// 填写活跃连接
void EpollPoller::fillActiveChannels(int numEvents, ChannelList* activeChannels) const{
for(int i = 0; i < numEvents; i++){
Channel *channel = static_cast<Channel*>(events_[i].data.ptr);
channel->set_revents(events_[i].events);
activeChannels->push_back(channel);//eventloop就拿到了它的poller给它返回的所有发生事件的channel列表
}
}
// 更新channel通道
void EpollPoller::update(int operation, Channel* channel){
struct epoll_event event;
memset(&event, 0, sizeof(event));
int fd = channel->fd();
event.events = channel->events();
event.data.ptr = channel;
event.data.fd = fd;
if(::epoll_ctl(epollfd_, operation, fd, &event) < 0){
if(operation == EPOLL_CTL_DEL){
//如果是删除失败,无伤大雅,报错就行
LOG_ERROR("epoll_ctl del error : %d\n", errno);
} else {
//如果是添加或者是修改操作出错,会影响后序的读写操作,这时候需要coredump退出
LOG_FATAL("epoll_ctl del error : %d\n", errno);
}
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。