libevent 源码学习七 —— 事件处理框架 event_base

前言 : 事件主循环是 libevent 事件处理的中心部分 1 事件处理主循环 a 开始 b 如果发现系统时间被向后调整了,就校正系统时间 c 根据 timer heap 中 event 的最小超时时间计算系统 I/O demultiplexer 的最大等待时间 d 更新 last wait time,并清空 time cache e 调用系统 I/O demultiplexer 等待就绪 I/O events f 检查 signal 的激活标记,如果被设置,则检查激活 signal event, 并把 event 插入到激活链表中 g 将就绪的 I/O events 插入到激活链表中 h 检查 heap 中的 timer events, 将就绪的 timer event 从 heap 上删除,并插入到激活链表中 i 根据优先级处理激活链表中的就绪 event, 调用其回调函数执行事件处理 j 结束 2 源码解析 int event_base_loop(struct event_base_loop *base, int flags){ const struct eventop *evsel = base -> evsel; void* evbase = base -> evbase; struct timeval tv; struct timeval *tv_P; int res, done; base -> tv_cache.tv_sec = 0; // 清空时间缓存 if(base -> sig.ev_signal_added) evsignal_base = base; done = 0; while(!done) // 事件主循环 { if(base -> event_gotterm) {// 可以调用 event_loopexit_cb() 设置 event_gotterm 标记 base -> event_gotterm = 0; break; } if(base -> event_break) {// 可以调用 event_base_loopbreak 设置 event_break 标记 base -> event_break = 0; break; } timeout_correct(base, &tv); // 校正系统时间 tv_p = &tv; if(!base -> event_count_active && !(flags & EVLOOP_NONBLOCK)) {// 计算系统 I/O demultiplexer 的最大等待时间 timeout_next(base, &tv_P); } else // 依然有未处理的就绪事件,就让 I/O demultiplexer 立即返回 evutil_timerclear(&tv) if(!event_haveevents(base)) {// 如果当前没有注册事件,就推出 event_debug(("%s: no events registered.", __func__)); return 1; } gettime(base, &base -> event_ev); base -> tv_cache.tv_sec = 0; // 调用系统 I/O demultiplexer 等待就绪 I/O events res = evsel -> dispatch(base, evbase, tv_p); if(res == -1) return -1; gettime(base, &base -> tvcache); // 检查 heap 中的 timer events,将就绪的 timer event 从 heap 上删除,并插入到激活链表中 timeout_process(base); if(base -> event_count_active) {// 调用 event_process_active() 处理激活链表中的就绪 event,调用其回调函数执行事件处理 // 该函数会优先处理最高优先级的激活事件链表,低优先级的就绪事件可能得不到及时处理 event_process_active(base); if(!base -> event_count_active && (flags & EVLOOP_ONCE)) done = 1; } else if(flags & EVLOOP_NONBLOCK) done = 1; } base -> tv_cache.tv_sec = 0; event_debug(("%s: asked to terminate loop", __func__)); return 0; } } 3 I/O 和 timer 事件的统一 LIbevent 将 timer 和 Signal 事件都统一到了系统的 I/O 的 demultiple 机制中了。 4 I/O 和 signal 事件的统一 Signal 是异步事件的经典事例,当信号发生时,并不立即调用 event 的 callback 函数处理信号。而是通知系统 I/O 机制,让其返回,然后再统一和 I/O 事件 以及 timer 一起处理
posted @ 2019-04-28 20:25  三二二,  阅读(275)  评论(0编辑  收藏  举报