libevent源代码分析——event_dispatch() (二)

在上篇文章中介绍关于event_dispatch的大体框架,这里对其中的几个重要的函数解释说明

1、timeout_correct(base,&tv)

static void
 889 timeout_correct(struct event_base *base, struct timeval *tv)
 890 {
 891     struct event **pev;
 892     unsigned int size;
 893     struct timeval off;
 894 
 895     if (use_monotonic)
 896         return;
 897 
 898     /* Check if time is running backwards */
 899     gettime(base, tv);
 900     if (evutil_timercmp(tv, &base->event_tv, >=)) {
 901         base->event_tv = *tv;
 902         return;
 903     }
 904 
 905     event_debug(("%s: time is running backwards, corrected",
 906             __func__));
 907     evutil_timersub(&base->event_tv, tv, &off);
 908 
 909     /*
 910      * We can modify the key element of the node without destroying
 911      * the key, beause we apply it to all in the right order.
 912      */
 913     pev = base->timeheap.p;
 914     size = base->timeheap.n;
 915     for (; size-- > 0; ++pev) {
 916         struct timeval *ev_tv = &(**pev).ev_timeout;
 917         evutil_timersub(ev_tv, &off, ev_tv);
 918     }
 919     /* Now remember what the new time turned out to be. */
 920     base->event_tv = *tv;
 921 }

这个函数的功能就是获取系统时间,在这个函数中调用的就是gettime(),在这个函数如果发现存放时间的缓冲区没有被清空,那么就使用当前保存的时间直接返回,如果缓冲区没有时间可以被利用,那么只能调用系统调用来获取时间,在上篇文章已经看到,很显然在event_base_loop中的第482行已经将时间缓冲区清空了,所以在这里使用gettime是不会在头两行就返回的。好像这里900行左右的代码是没有什么作用的,907行的比较函数时间值的大小。514行的判断:如果当前的激活事件为0,也就是没有什么激活事件,那么就提取一个时间,这个时间是将来要循环的最大时间。

static void
 365 event_process_active(struct event_base *base)
 366 {
 367     struct event *ev;
 368     struct event_list *activeq = NULL;
 369     int i;
 370     short ncalls;
 371 
 372     for (i = 0; i < base->nactivequeues; ++i) {
 373         if (TAILQ_FIRST(base->activequeues[i]) != NULL) {
 374             activeq = base->activequeues[i];
 375             break;
 376         }
 377     }
 378 
 379     assert(activeq != NULL);
 380 
 381     for (ev = TAILQ_FIRST(activeq); ev; ev = TAILQ_FIRST(activeq)) {
 382         if (ev->ev_events & EV_static void
 365 event_process_active(struct event_base *base)
 366 {
 367     struct event *ev;
 368     struct event_list *activeq = NULL;
 369     int i;
 370     short ncalls;
 371 
 372     for (i = 0; i < base->nactivequeues; ++i) {
 373         if (TAILQ_FIRST(base->activequeues[i]) != NULL) {
 374             activeq = base->activequeues[i];
 375             break;
 376         }
 377     }
 378 
 379     assert(activeq != NULL);
 380 
 381     for (ev = TAILQ_FIRST(activeq); ev; ev = TAILQ_FIRST(activeq)) {
 382         if (ev->ev_events & EV_PERSIST)
 383             event_queue_remove(base, ev, EVLIST_ACTIVE);
 384         else
 385             event_del(ev);
 386 
 387         /* Allows deletes to work */
 388         ncalls = ev->ev_ncalls;
 389         ev->ev_pncalls = &ncalls;
 390         while (ncalls) {
 391             ncalls--;
 392             ev->ev_ncalls = ncalls;
 393             (*ev->ev_callback)((int)ev->ev_fd, ev->ev_res, ev->ev_arg);
 394             if (event_gotsig || base->event_break)
 395                 return;
 396         }
 397     }
 398 }

)
 383             event_queue_remove(base, ev, EVLIST_ACTIVE);
 384         else
 385             event_del(ev);
 386 
 387         /* Allows deletes to work */
 388         ncalls = ev->ev_ncalls;
 389         ev->ev_pncalls = &ncalls;
 390         while (ncalls) {
 391             ncalls--;
 392             ev->ev_ncalls = ncalls;
 393             (*ev->ev_callback)((int)ev->ev_fd, ev->ev_res, ev->ev_arg);
 394             if (event_gotsig || base->event_break)
 395                 return;
 396         }
 397     }
 398 }
注意382行,这一行可以发现,在自己添加event的时候,如果不是 EV_PERSIST,那么在这个event被响应一次,下一次这个event会被自动删除。event_process_active已经是处理事件了,但是添加事件实在timeout_process.

 void
 924 timeout_process(struct event_base *base)
 925 {
 926     struct timeval now;
 927     struct event *ev;
 928 
 929     if (min_heap_empty(&base->timeheap))
 930         return;
 931 
 932     gettime(base, &now);
 933 
 934     while ((ev = min_heap_top(&base->timeheap))) {
 935         if (evutil_timercmp(&ev->ev_timeout, &now, >))
 936             break;
 937 
 938         /* delete this event from the I/O queues */
 939         event_del(ev);
 940 
 941         event_debug(("timeout_process: call %p",
 942              ev->ev_callback));
 943         event_active(ev, EV_TIMEOUT, 1);
 944     }
 945 }
 
943行标志着这个事件已经被添加到激活链表中了,这个函数调用了insert函数


libevent源代码分析——event_dispatch() (二)

上一篇:深入学习虚拟机类加载过程


下一篇:多线程程序