原生epoll一共只有三个库函数接口,已经足够简洁,但具体使用上各种代码实现依旧千差万别,这里对epoll做了个简单的接口封装,以供参考,本人水平有限,不足之处欢迎指教。
代码如下:
event_epoll.h
#ifndef EVENT_EPOLL_H_
#define EVENT_EPOLL_H_
#include <functional>
#include <sys/epoll.h>
class Epoll
{
private:
typedef std::function<void (int fd, void *ctx, int revents)> event_handler;
struct fd_node
{
fd_node(): fd(-1), ctx(NULL), handler(NULL) {}
int fd;
void *ctx;
event_handler handler;
};
public:
Epoll(): epoll_fd_(-1), maxfds_(-1), fd_nodes_(NULL), epoll_events_(NULL) {}
public:
int Init(int maxfds);
int Free();
int Register(int fd, event_handler handler, void *ctx);
int Unregister(int fd);
int EventAdd(int fd, int events);
int EventDel(int fd);
int Poll(int timeout_ms);
private:
int epoll_fd_;
int maxfds_;
fd_node **fd_nodes_;
epoll_event *epoll_events_;
};
#endif /*EVENT_EPOLL_H_*/
#include <unistd.h>
#include <string.h>
#include "event_epoll.h"
int Epoll::Init(int maxfds)
{
epoll_fd_ = epoll_create(maxfds);
if (-1 == epoll_fd_) return -1;
maxfds_ = maxfds;
fd_nodes_ = new fd_node *[maxfds];
epoll_events_ = new epoll_event[maxfds];
return 0;
}
int Epoll::Free()
{
close(epoll_fd_);
delete epoll_events_;
for (int i = 0; i < maxfds_; i++)
{
if (fd_nodes_[i]) delete fd_nodes_[i];
}
delete []fd_nodes_;
return 0;
}
int Epoll::Register(int fd, event_handler handler, void *ctx)
{
fd_node *fdn;
if (fd >= maxfds_) return -1;
fdn = new fd_node;
fdn->handler = handler;
fdn->fd = fd;
fdn->ctx = ctx;
fd_nodes_[fd] = fdn;
return 0;
}
int Epoll::Unregister(int fd)
{
if (fd >= maxfds_) return -1;
delete fd_nodes_[fd];
fd_nodes_[fd] = NULL;
return 0;
}
int Epoll::EventAdd(int fd, int events)
{
fd_node *fdn;
struct epoll_event ep;
if (fd >= maxfds_) return -1;
fdn = fd_nodes_[fd];
ep.events = events;
ep.data.ptr = fdn;
if (0 != epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, fd, &ep))
{
return -1;
}
return 0;
}
int Epoll::EventDel(int fd)
{
struct epoll_event ep;
if (0 != epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, fd, &ep))
{
return -1;
}
return 0;
}
int Epoll::Poll(int timeout_ms)
{
int n;
int events;
fd_node *fdn;
n = epoll_wait(epoll_fd_, epoll_events_, maxfds_, timeout_ms);
for (int i = 0; i < n; i++)
{
events = epoll_events_[i].events;
fdn = (fd_node *)epoll_events_[i].data.ptr;
fdn->handler(fdn->fd, fdn->ctx, events);
}
return n;
}