在上篇文章中介绍关于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 }
libevent源代码分析——event_dispatch() (二)
原文:http://blog.csdn.net/yusiguyuan/article/details/18263705