PinkEpoll
PinkEpoll
对外提供了为socket fd注册事件、修改注册事件、等待事件触发接口
struct PinkFiredEvent {
int fd_;
int mask_;
};
class PinkEpoll{
public:
PinkEpoll();
~PinkEpoll();
//注册事件
Status PinkAddEvent(int fd, int mask);
//从epfd中删除一个fd
void PinkDelEvent(int fd);
//修改已经注册的fd的监听事件
Status PinkModEvent(int fd, int oMask, int mask);
//等待事件触发
int PinkPoll(int timeout);
//得到所有的触发事件
PinkFiredEvent *firedevent() { return firedevent_; }
private:
int epfd_;
struct epoll_event *events_;
int timeout_;
PinkFiredEvent *firedevent_;
};
构造函数
PinkEpoll::PinkEpoll()
{
#if defined(EPOLL_CLOEXEC)
epfd_ = epoll_create1(EPOLL_CLOEXEC);
#else
epfd_ = epoll_create(1024);
#endif
fcntl(epfd_, F_SETFD, fcntl(epfd_, F_GETFD) | FD_CLOEXEC);
if (epfd_ < 0) {
log_err("epoll create fail");
exit(1);
}
events_ = (struct epoll_event *)malloc(sizeof(struct epoll_event) * PINK_MAX_CLIENTS);
if (!events_) {
log_err("init epoll_event error");
}
timeout_ = 1000;
firedevent_ = (PinkFiredEvent *)malloc(sizeof(PinkFiredEvent) * PINK_MAX_CLIENTS);
}
PinkEpoll::~PinkEpoll()
{
free(firedevent_);
free(events_);
close(epfd_);
}
注册事件
Status PinkEpoll::PinkAddEvent(int fd, int mask)
{
struct epoll_event ee;
ee.data.fd = fd;
ee.events = mask;
if (epoll_ctl(epfd_, EPOLL_CTL_ADD, fd, &ee) == -1) {
return Status::Corruption("epollAdd error");
}
return Status::OK();
}
修改已经注册事件
Status PinkEpoll::PinkModEvent(int fd, int oMask, int mask)
{
struct epoll_event ee;
ee.data.fd = fd;
ee.events = (oMask | mask);
if (epoll_ctl(epfd_, EPOLL_CTL_MOD, fd, &ee) == -1) {
return Status::Corruption("epollCtl error");
}
return Status::OK();
}
从epfd中删除一个fd
void PinkEpoll::PinkDelEvent(int fd)
{
/*
* Kernel < 2.6.9 need a non null event point to EPOLL_CTL_DEL
*/
struct epoll_event ee;
ee.data.fd = fd;
epoll_ctl(epfd_, EPOLL_CTL_DEL, fd, &ee);
}
等待事件触发
int PinkEpoll::PinkPoll(int timeout)
{
int retval, numevents = 0;
retval = epoll_wait(epfd_, events_, PINK_MAX_CLIENTS, timeout);
if (retval > 0) {
numevents = retval;
for (int i = 0; i < numevents; i++) {
int mask = 0;
firedevent_[i].fd_ = (events_ + i)->data.fd;
/*
* log_info("events + i events %d", (events_ + i)->events);
*/
if ((events_ + i)->events & EPOLLIN) {
mask |= EPOLLIN;
}
if ((events_ + i)->events & EPOLLOUT) {
mask |= EPOLLOUT;
}
if ((events_ + i)->events & EPOLLERR) {
mask |= EPOLLERR;
}
if ((events_ + i)->events & EPOLLHUP) {
mask |= EPOLLHUP;
}
firedevent_[i].mask_ = mask;
}
}
return numevents;
}