5 事件接口设计
1 数据结构
1.1 事件实体 event_s
struct event_s {
int ev_fd;
void (*ev_callback)(int, int, void *ev_arg);
void *ev_arg;
int ev_events;
int ev_status;
};
说明:
每个事件有一个描述符,并且有相应的回调函数,函数参数,事件属性,事件状态。
2 接口函数
2.1 事件设置event_set
函数签名:
void event_set(event_t ev, int fd, void (call_back)(int, int, void ), void arg)
函数实体:
void event_set(event_t *ev, int fd, void (*call_back)(int, int, void *), void *arg) {
ev->ev_fd = fd;
ev->ev_callback = call_back;
ev->ev_arg = arg;
ev->ev_events = 0;
ev->ev_status = 0;
return ;
}
函数说明:
给传入的事件设置相应的描述符,回调函数,和函数参数,并且初始化事件的状态
2.2 增加事件event_add
函数签名:
event_add(int ep_fd, int events, event_t *ev, int et_flag)
函数实体:
void event_add(int ep_fd, int events, event_t *ev, int et_flag) {
struct epoll_event ep_event = {0, {0}};
int option;
if (et_flag) {
fcntl(ev->ev_fd, F_SETFL, O_NONBLOCK);
events |= EPOLLET;
}
ep_event.data.fd = ev->ev_fd;
ep_event.events = ev->ev_events = events;
if (ev->ev_status == 1) {
option = EPOLL_CTL_MOD;
} else {
option = EPOLL_CTL_ADD;
ev->ev_status = 1;
}
if (epoll_ctl(ep_fd, option, ev->ev_fd, &ep_event) < 0) {
perror("epoll ctl error");
exit(-1);
}
return ;
}
说明:
将事件添加到 epoll 中,使用非阻塞 ET 的触发模式。
2.3 删除事件event_del
函数签名:
event_del(int ep_fd, event_t *ev)
函数实体:
void event_del(int ep_fd, event_t *ev) {
int option;
if (ev->ev_fd == -1)
return ;
option = EPOLL_CTL_DEL;
if ((epoll_ctl(ep_fd, option, ev->ev_fd, 0)) < 0) {
perror("del event error");
return ;
}
}
函数说明:
从epoll中删除传入的事件,根据事件的描述符