量*/
int event_count; /**< counts number of total events */
int event_count_active; /**< counts number of active events */
/* 是否执行完活动事件队列上的剩余任务之后就退出事件循环 */
int event_gotterm; /**< Set to terminate loop once done
* processing events. */
/* 是否立即退出事件循环,而不管是否还有任务需要处理 */
int event_break; /**< Set to exit loop immediately */
/* 活动事件队列数组。索引越小的队列,优先级越高。高优先级的活动事件队列中的事件处理器将被优先处理*/
struct event_list **activequeues;
/* 活动事件队列数组的大小,即该event_base一共有nactivequeues个不同优先级的活动事件队列*/
int nactivequeues;
/*是否应该启动一个新的事件循环*/
int event_continue;
//目前正在处理的活动事件队列的优先级
int event_running_priority;
//事件循环是否已经启动
int running_loop;
/** Deferred callback management: a list of deferred callbacks to
* run active the active events. */
TAILQ_HEAD (deferred_cb_list, deferred_cb) deferred_cb_list;
//文件描述符和IO事件之间的映射关系表
struct event_io_map io;
/*信号值和信号事件之间的映射关系表*/
struct event_signal_map sigmap;
/*注册时间队列,存放IO事件处理器和信号事件处理器*/
struct event_list eventqueue;
/*时间堆*/
struct min_heap timeheap;
//系统管理时间的一些成员
struct timeva l event_tv;
struct timeva l tv_cache;
};
其中:
事件主循环主要是通过event_base_loop()函数来完成的。其代码如下:
int event_base_loop(struct event_base *base, int flags){
const struct eventop *evsel = base->evsel;
void *evbase = base->evbase;
struct timeva l tv;
struct timeva l *tv_p;
int res, done;
//清空时间缓存
base->tv_cache.tv_sec = 0;
//evsignal_base是全局变量,在处理signal时,用于指明signal所属的event_base实例
if(base->sig.ev_signal_added)
evsignal_base = base;
done = 0;
//事件主循环
while(!done){
//查看是否需要跳出循环,程序可以调用event_loopexit_cb()设置event_gotterm标记
//调用event_base_loopbreak设置event_break标志
if(base->event_gotterm){
base->event_gotterm = 0;
break;
}
if(base->event_break){
base->event_break = 0;
break;
}
//you cannot use this interface for multi-threaded apps
while(event_gotsig){
event_gotsig = 0;
if(event_sigcb){
res = (*event_sigcb)();
if(res == -1){
errno = EINTR;
return -1;
}
}
}
//校正系统时间,如果系统使用的是非MONOTONIC时间,用户可能会向后调整了系统时间
//在timeout_correct函数中,比较last wait time和当前事件,如果
//当前时间 < last wait time
//表明时间有问题,这需要更新timer_heap中所有定时事件的超时时间
timeout_correct(base, &tv);
//根据time heap中事件的最小超时时间,计算系统IO demultiplexer的最大等待时间
tp_p = &tv;
if(!base->event_count_active && !(flags & EVLOOP_NONBLOCK)){
timeout_next(base, &tv_p);
}
else{
//依然有未处理的就绪时间,就让IO demultiplexer立即返回,不必等待
//下面会提到,在libevent中,低优先级的就绪事件可能不能立即被处理
evutil_timerclear(&tv);
}
//如果当前没有注册事件,就退出
if(!event_haveevents(base)){
event_debug("%s: no events registered.", __func__);
return 1;
|