C++ Epoll的封装

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);
}

你可能感兴趣的:(UNIX/LINUX,C/C++)