libevent 源码学习五 —— 事件 event
前言 : event 是 libevent 的核心结构。
1. libevent 的核心 —— event
libevent 是基于事件驱动的,event 是 Reactor 框架中的事件处理程序组件;它提供了函数接口,供 Reactor 在事件发生时调用以执行相应的事件处理,通常会绑定一个有效的句柄
event 结构体的声明位于 event2/event_struct.h 头文件中
struct event {
TAILQ_ENTRY (event) ev_next;
TAILQ_ENTRY (event) ev_active_next;
TAILQ_ENTRY (event) ev_signal_next;
unsigned int min_heap_idx; /* for managing timeouts */
struct event_base *ev_base;
int ev_fd;
short ev_events;
short ev_ncalls;
short *ev_pncalls; /* Allows deletes in callback */
struct timeval ev_timeout;
int ev_pri; /* smaller numbers are higher priority */
void (*ev_callback)(int, short, void *arg);
void *ev_arg;
int ev_res; /* result passed to event callback */
int ev_flags;
};
ev_events : event 关注的事件类型 :I/O 事件(EV_WRITE和EV_READ) 定时事件(EV_TIMEOUT) 信号(EV_SIGNAL)辅助选项EV_PERSIST:表明是一个永久事件
ev_next, ev_active_next 和 ev_signal_next 都是双向链表节点指针;它们是libevent对不同事件类型和在不同的时期,对事件的管理时使用到的字段。
min_heap_idx 和 ev_timeout, 如果是 timeout 事件,它们是 event 在小根堆中的索引和超时值,libevent 使用小根堆来管理定时事件。
ev_base 该事件所属的反应堆实例,这是一个event_base 结构体。
ev_fd : 对于 I/O 事件, 是绑定的文件描述符,对于 signal 事件 是绑定的信号
ev_callback,event 的回调函数,被ev_base调用,执行事件处理程序,是一个函数指针:void (*ev_callback)(int fd, short events, void *arg)
ev_arg : void* ,表明可以是任意类型的数据,在设置 event 时指定
ev_flags: libevent 用于标记 event 信息的字段,表明其当前的状态。
ev_ncalls:事件就绪时,调用ev_callback 的次数,通常为1
ev_pnacalls: 指针,通常指向 ev_ncalls 或者为 NULL
ev_res : 记录了当前激活事件的类型
2. libevent 对 event 的管理
每当有事件 event 转变为就绪状态时,libevent 就会把它移入到 active event list [priority] 中,
接着 libevent 会根据自己的调度策略选择就绪事件,调用其 cb_callback()函数执行事件处理;并根据就绪的句柄和事件类型填充cb_callback函数的参数
3 事件设置的接口函数
要向 libevent 添加一个事件,需要首先设置 event 对象,这通过调用 libevent 提供的函数有: event_set(), event_base_set(),event_priority_set() 来完成:
void event_set(struct event *ev, int fd, short events, void (*callback)(int, short, void *), void *arg)
设置事件的文件描述符,设置事件类型, 事件回调函数和参数, 初始化其他字段
int event_base_set(struct event_base *base, struct event *ev )
libevent 有一个全局的 event_base 指针 current_base, 默认情况下事件 ev 将被注册到 current_base 上,使用该函数可以在指定不同的 event_base
int event_priority_set(struct event *ev, int pri)
设置 event_ev 的优先级,ev 处于就绪状态时不能设置