C++ Epoll的封装

来源:互联网 发布:褥子什么材质的好 知乎 编辑:程序博客网 时间:2024/05/22 13:21
Epoller组件的实现主要是对于epoll_create,epoll_ctl,epoll_wait等的封装,该Epoll可以设置
  • 可选择采用边缘触发还是选择触发的模式bEt,默认为边缘触发 
  • 可指定该Epoll可以指定监听的最大套接字数目max_connections

/**
 * @brief epoller操作类,已经默认采用了EPOLLET方式做触发
 */
class TC_Epoller
{
public:

     /**
      * @brief 构造函数.
      * 
     * @param bEt 默认是ET模式,当状态发生变化的时候才获得通知
      */
     TC_Epoller(bool bEt = true);

     /**
     * @brief 析够函数.
      */
     ~TC_Epoller();

     /**
      * @brief 生成 epoll句柄.
      * 
     * @param max_connections epoll服务需要支持的最大连接数
      */
     void create(int max_connections);

     /**
      * @brief 添加监听句柄.
      * 
     * @param fd    句柄
     * @param data  辅助的数据, 可以后续在epoll_event中获取到
     * @param event 需要监听的事件EPOLLIN|EPOLLOUT
     *             
      */
     void add(int fd, long long data, __uint32_t event);

     /**
      * @brief 修改句柄事件.
      * 
     * @param fd    句柄
     * @param data  辅助的数据, 可以后续在epoll_event中获取到
     * @param event 需要监听的事件EPOLLIN|EPOLLOUT
      */
     void mod(int fd, long long data, __uint32_t event);

     /**
      * @brief 删除句柄事件.
      * 
     * @param fd    句柄
     * @param data  辅助的数据, 可以后续在epoll_event中获取到
     * @param event 需要监听的事件EPOLLIN|EPOLLOUT
      */
     void del(int fd, long long data, __uint32_t event);

     /**
      * @brief 等待时间.
      * 
      * @param millsecond 毫秒
     * @return int       有事件触发的句柄数
      */
     int wait(int millsecond);

     /**
     * @brief 获取被触发的事件.
      *
      * @return struct epoll_event&被触发的事件
      */
     struct epoll_event& get(int i) { assert( _pevs != 0); return _pevs [i]; }

protected:

     /**
      * @brief 控制 epoll,将EPOLL设为边缘触发EPOLLET模式
     * @param fd    句柄,在create函数时被赋值
     * @param data  辅助的数据, 可以后续在epoll_event中获取到
     * @param event 需要监听的事件
      * @param op    EPOLL_CTL_ADD: 注册新的 fdepfd 中;
      *                  EPOLL_CTL_MOD:修改已经注册的 fd的监听事件;
      *                  EPOLL_CTL_DEL:从 epfd中删除一个fd
      * 
      */
     void ctrl(int fd, long long data, __uint32_t events, int op);

protected:

    /**
     *      epoll
     */
    int _iEpollfd;

     /**
     * 最大连接数
      */
     int   _max_connections;

     /**
     * 事件集
      */
     struct epoll_event *_pevs;

    /**
     * 是否是ET模式
     */
    bool _et;
};


TC_Epoller::TC_Epoller(bool bEt)
{
     _iEpollfd   = -1;
     _pevs       = NULL;
    _et         = bEt;
     _max_connections = 1024;
}

TC_Epoller::~TC_Epoller()
{
     if(_pevs != NULL)
     {
            delete[] _pevs;
            _pevs = NULL;
     }

     if(_iEpollfd > 0)
     {
            close(_iEpollfd);
     }
}

void TC_Epoller::ctrl(int fd, long long data, __uint32_t events, int op)
{
     struct epoll_event ev;
     ev.data.u64 = data;
    if(_et)
    {
        ev.events   = events | EPOLLET ;
    }
    else
    {
        ev.events   = events;
    }

     epoll_ctl(_iEpollfd , op, fd, &ev);
}

void TC_Epoller::create(int max_connections)
{
     _max_connections = max_connections;

     _iEpollfd = epoll_create(_max_connections + 1);

     if(_pevs != NULL)
     {
            delete[] _pevs;
     }

     _pevs = new epoll_event[_max_connections + 1];
}

void TC_Epoller::add(int fd, long long data, __uint32_t event)
{
     ctrl(fd, data, event, EPOLL_CTL_ADD);
}

void TC_Epoller::mod(int fd, long long data, __uint32_t event)
{
     ctrl(fd, data, event, EPOLL_CTL_MOD);
}

void TC_Epoller::del(int fd, long long data, __uint32_t event)
{
     ctrl(fd, data, event, EPOLL_CTL_DEL);
}

int TC_Epoller::wait(int millsecond)
{
     return epoll_wait(_iEpollfd , _pevs , _max_connections + 1, millsecond);
}

原创粉丝点击