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: 注册新的 fd到epfd 中;
* 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);
}