这里分析的是libevent-1.4.9。
PS:前面还看了libev的源代码,妈的,那代码写的太猥亵了,相比较libevent代码写的好多了。。
首先来看一下最主要的几个数据结构:
eventop结构体是所有事件驱动模型的基类。所有的io复用类型都会实现此结构体里各种方法。
struct eventop {
const char *name; ///<事件驱动名称
void *(*init)(struct event_base *); //<初始化
int (*add)(void *, struct event *); ///<加入新的事件监测
int (*del)(void *, struct event *); ///<从事件监测中删除某一事件
int (*dispatch)(struct event_base *, void *, struct timeval *);///<启动此事件监测
void (*dealloc)(struct event_base *, void *); ///<释放此事件驱动的资源
/* set if we need to reinitialize the event base */
int need_reinit; ///<标志位
};
event_base管理所有的event对象,它包含了一些全部变量,比如事件驱动引擎evsel等。所有的event对象都会包含这个结构体。
struct event_base {
const struct eventop *evsel; ///<事件驱动引擎
void *evbase; ///<事件驱动引擎的全局数据,在每一个事件引擎文件中定义,下面会介绍.
int event_count; /* counts number of total events */
int event_count_active; /* counts number of active events */
int event_gotterm; /* Set to terminate loop */
int event_break; /* Set to terminate loop immediately */
/* active event management */
struct event_list **activequeues; ///<激活队列
int nactivequeues; ///<激活队列数目
/* signal handling info */
struct evsignal_info sig; ///<信号
struct event_list eventqueue; ///<全部事件队列
struct timeval event_tv;
struct min_heap timeheap; ///<这里libevent将定时器队列实现为一个最小堆,也就是为了每次都把时间最晚的定时器能取出来,然后实现超时。更其实算法很简单,想要详细的了解可以去看下算法导论的第六章的Priority queues.
struct timeval tv_cache;
};
event结构表示每个事件,包含了一些事件私有的数据,比如回调函数等。。这里事件链表它使用了tail queue.
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; ///<全局的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;
};