在上篇文章中介绍关于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 }