Libevent源码剖析——事件event

Libevent 是基于事件驱动(event-driven)的,从名字也可以看到 event 是整个库的核心。event 就是 Reactor 框架中的事件处理程序组件;它提供了函数接口,供 Reactor 在事件发生时调用,以执行相应的事件处理,通常它会绑定一个有效的句柄。首先给出 event 结构体的声明,它位于 event.h 文件中,我直接给出带注释的代码:

//一个event管理三种事件,I/O事件,信号事件和定时事件
struct event {

	/* 三个都是TAILQ类型的双向链表队列的节点内的前后索引,他们是libevent对不同事件
	 * 类型和在不同的时期对事件的管理时使用到的字段。
	 * 这个TAILQ_ENTRY分别存储了在各自队列的前驱和后续节点
	 * 也就表示了这个event在不同队列里面的节点位置
	 * 这里有一个设计技巧,将位置索引指针与节点value值进行解耦,可以让同一个节点
	 * 出现在不同数据结构(链表,min_head)中。
	 */

	/*在I/O事件链表中的位置*/
	TAILQ_ENTRY (event) ev_next;  

	/*在激活事件链表中的位置*/
	TAILQ_ENTRY (event) ev_active_next; 
	
	/*在signal事件链表中的位置*/
	TAILQ_ENTRY (event) ev_signal_next; 

	/* 如果event是signal类型事件,
	 * min_heap_idx记录了它们是event在小根堆中的索引
	 * ev_timeout记录了超时值,libevent使用小根堆来管理定时事件*/
	unsigned int min_heap_idx;	/* for managing timeouts */

	/*event在小根堆中的超时值*/
	struct timeval ev_timeout;

	/*该事件event所属的event_base结构体*/
	struct event_base *ev_base;

	/*对于I/O事件,是绑定的文件描述符;对于signal事件,是绑定的信号类型;
	 *回忆APUE,信号和文件描述符都是整数值*/
	int ev_fd;

	 /* event关注的事件类型。 
	  * I/O事件: EV_WRITE和EV_READ,
	  * 定时事件:EV_TIMEOUT
          * 信号:    EV_SIGNAL
          * 辅助选项:EV_PERSIST,表明是一个永久事件
          * #define文件中进行了定义。可以用‘|’运算进行组合
          * 信号时间和I/O事件不能同时设置。
	  * 根据这一字段不同表示当前event表示哪种事件类型
	  * 进一步表明libevent使用event结构体将这3种事件的处理统一起来;
      */
	short ev_events; 

	/*事件就绪执行时,调用ev_callback的次数,通常为1*/ 
	short ev_ncalls;

	/*指针,通常指向ev_ncalls或者为NULL*/
	short *ev_pncalls;	/* Allows deletes in callback */

	/*事件的优先级,数字越小,优先级越大*/
	/*Libevent的就绪事件调度策略*/
	int ev_pri;		/* smaller numbers are higher priority */

	/*event的回调函数,被ev_base调用,执行事件处理程序*/
	void (*ev_callback)(int, short, void *arg);

	/*表明可以是任意类型的数据,在设置event时指定*/
	void *ev_arg;

	/*记录了当前激活事件的类型*/
	int ev_res;		/* result passed to event callback */

	/*libevent用于标记event信息的字段,表明其当前的状态,可能的值有:见第一个#define*/
	int ev_flags;
};
其中,ev_flags的宏定义类型有:

#define EVLIST_TIMEOUT	0x01 // event在time堆中 
#define EVLIST_INSERTED	0x02 // event在已注册事件链表中
#define EVLIST_SIGNAL	0x04 // 未见使用 
#define EVLIST_ACTIVE	0x08 // event在激活链表中
#define EVLIST_INTERNAL	0x10 // 内部使用标记  
#define EVLIST_INIT	0x80 // event已被初始化 








你可能感兴趣的:(Libevent源码剖析)