libev库源码分析系列教程(三)
源码分析mettle后门工具学习 所使用的依赖库
官网:http://securitytech.cc
libev 源码深度解析
1. 核心源码文件结构
1.1 主要源文件功能划分
libev-4.33/├── ev.h # 核心API声明和基础数据结构├── ev.c # 核心实现和主事件循环逻辑├── ev_vars.h # 全局变量声明宏定义├── ev_wrap.h # 多实例支持包装器├── ev++.h # C++绑定接口├── event.h # libevent兼容API├── ev_select.c # select后端实现├── ev_poll.c # poll后端实现├── ev_epoll.c # epoll后端实现 (Linux)├── ev_kqueue.c # kqueue后端实现 (BSD)├── ev_port.c # event ports后端实现 (Solaris)└── ev_win32.c # Windows平台实现
2. 核心数据结构源码分析
2.1 Watcher基础结构实现
ev.h中的核心定义
/* Watcher基础宏定义 */#defineEV_WATCHER(type) \ int active;/* active状态: 0=未激活, 1+=优先级+1 */\intpending;/* pending计数: 0=无pending, 1+=pending队列位置 */\intpriority;/* 优先级: 0=最高, NUMPRI-1=最低 */\void*data;/* 用户自定义数据指针 */\structev_watcher*next;/* 双向链表指针 */\structev_watcher*prev;/* 时间相关Watcher扩展 */#defineEV_WATCHER_TIME(type) \ EV_WATCHER(type) \ ev_tstamp at;/* 绝对超时时间 *//* 具体Watcher类型定义 */typedefstruct{EV_WATCHER(ev_io)intfd;/* 文件描述符 */intevents;/* 监听事件(POLLIN/POLLOUT等) */}ev_io;typedefstruct{EV_WATCHER_TIME(ev_timer)ev_tstamprepeat;/* 重复间隔(0=一次性) */}ev_timer;
2.2 事件循环结构详解
ev_loop的内存布局 (ev_vars.h)
/* 核心变量宏定义系统 */#defineVAR(type,name,init,destructor,value) \ type name;/* 实际结构体生成 */structev_loop{#include"ev_vars.h"/* 展开所有变量定义 */};/* 关键字段分析 */VAR(int,backend_fd, , ,0)// 后端文件描述符VAR(ev_tstamp,now_floor, , ,0.)// 当前时间缓存VAR(int,pendingpri, , ,0)// 当前处理的pending优先级VAR(ev_watcher*,pending, [NUMPRI], ,0)// pending队列数组VAR(ev_watcher_list*,anfds, , ,0)// fd到watcher映射表
3. 核心算法实现源码
3.1 时间堆算法实现
最小堆操作函数 (ev.c)
/* 堆上浮操作 */inline_sizevoidupheap(ANHE*heap,intpri,intk) {ANHEhe=heap[k];while(k>HEAP0&&ANHE_at(he)<ANHE_at(heap[HPARENT(k)])) {heap[k]=heap[HPARENT(k)];ev_active(ANHE_w(heap[k]))=k--; }heap[k]=he;ev_active(ANHE_w(he))=k; }/* 堆下沉操作 */inline_sizevoiddownheap(ANHE*heap,intpri,intk) {ANHEhe=heap[k];for(;;) {intc=HEAP0+(k-HEAP0)*2;if(c>= (HEAP0+timercnt[pri]))break;c+=c+1<(HEAP0+timercnt[pri])&&ANHE_at(heap[c])>ANHE_at(heap[c+1]);if(ANHE_at(he) <=ANHE_at(heap[c]))break;heap[k]=heap[c];ev_active(ANHE_w(heap[k]))=k;k=c; }heap[k]=he;ev_active(ANHE_w(he))=k; }
3.2 事件分发核心逻辑
主事件循环实现 (ev.c)
// 核心事件处理函数intev_run (EV_P_intflags) { ++loop_depth; while (ecb_expect_true (activecnt||loop_done||pendingcnt)) { if (ecb_expect_false (loop_done)) break; /* 阶段1: prepare watchers */EV_INVOKE_PENDING; // 处理pending事件if (ecb_expect_false (pendingcnt<0)) pendingcnt=0; /* 阶段2: 调度计算 */ev_tstamptimeout=0.; if (ecb_expect_true (!(flags&EVRUN_NOWAIT||idleall|| !activecnt))) { timeout=MAX_BLOCKING_INTERVAL; if (timercnt [LOW]) { ev_tstampto=ANHE_at (timerv [LOW][HEAP0]) -ev_rt_now; if (to<timeout) timeout=to; } } /* 阶段3: backend轮询 */backend_poll (EV_A_timeout); /* 阶段4: 处理就绪事件 */EV_INVOKE_PENDING; /* 阶段5: check watchers */ } --loop_depth; returnactivecnt; }
4. Backend后端实现分析
4.1 epoll后端源码 (ev_epoll.c)
初始化函数
staticvoidepoll_init (EV_P_intflags) { if (!epoll_eventmax) epoll_eventmax=64; epoll_events= (structepoll_event*)ev_malloc (sizeof (structepoll_event) *epoll_eventmax);#ifdefEPOLL_CLOEXECbackend_fd=epoll_create1 (EPOLL_CLOEXEC); if (backend_fd<0&& (errno==EINVAL||errno==ENOSYS))#endifbackend_fd=epoll_create (epoll_eventmax); if (backend_fd<0) return; fcntl (backend_fd, F_SETFD, FD_CLOEXEC); fd_change (EV_A_backend_fd, EV__IOFDSET);}
事件轮询实现
staticvoidepoll_poll (EV_P_ev_tstamptimeout) { intres=epoll_wait (backend_fd, epoll_events, epoll_eventmax, epoll_wait_timeout (timeout)); for (inti=0; i<res; ++i) { structepoll_event*e=epoll_events+i; intfd=e->data.fd; if (ecb_expect_true (fd >= 0&&fd<anfdmax&&anfds [fd].events)) fd_event (EV_A_fd, e->events); elsepipe_write_wanted=1; /* probably a pipe was closed */ } }
4.2 kqueue后端源码 (ev_kqueue.c)
kqueue特有的事件类型处理
staticvoidkqueue_poll (EV_P_ev_tstamptimeout) { structtimespects; ts.tv_sec= (long)timeout; ts.tv_nsec= (long)((timeout- (long)timeout) *1e9); intres=kevent (backend_fd, 0, 0, kqueue_changes, kqueue_changemax, &ts); for (inti=0; i<res; ++i) { structkevent*kev=kqueue_events+i; intfd=kev->ident; if (kev->filter==EVFILT_READ) fd_event (EV_A_fd, EV_READ); elseif (kev->filter==EVFILT_WRITE) fd_event (EV_A_fd, EV_WRITE); elseif (kev->filter==EVFILT_SIGNAL) ev_feed_signal_event (EV_A_kev->ident); } }
5. 内存管理源码分析
5.1 对象池实现
内存池管理结构
/* 内存池节点定义 */structev_walk{ inttype; // 对象类型标识intsize; // 对象大小void*mem; // 内存块指针structev_walk*next; // 链表指针};/* 预定义的对象池 */staticstructev_walkmempool[] = { { EV_IO, sizeof(ev_io), 0, 0 }, { EV_TIMER, sizeof(ev_timer), 0, 0 }, { EV_PERIODIC, sizeof(ev_periodic), 0, 0 }, { EV_SIGNAL, sizeof(ev_signal), 0, 0 }, { EV_CHILD, sizeof(ev_child), 0, 0 }, { EV_STAT, sizeof(ev_stat), 0, 0 }, { EV_IDLE, sizeof(ev_idle), 0, 0 }, { EV_PREPARE, sizeof(ev_prepare), 0, 0 }, { EV_CHECK, sizeof(ev_check), 0, 0 }, { EV_EMBED, sizeof(ev_embed), 0, 0 }, { EV_FORK, sizeof(ev_fork), 0, 0 }, { EV_ASYNC, sizeof(ev_async), 0, 0 }, { EV_CLEANUP, sizeof(ev_cleanup), 0, 0 }, { 0, 0, 0, 0 } };
5.2 动态数组扩容机制
文件描述符数组扩容
staticvoidnoinlinearray_needsize (void*base, int*cur, intmax, intelement_size, void*(*cb)(void*base, int*cur, intmax)) { if (max>*cur) { void*newbase=cb (base, cur, max); if (newbase) { memset ((char*)newbase+*cur*element_size, 0, (max-*cur) *element_size); *cur=max; } } }/* fd数组扩容回调 */staticvoid*anfds_resize (void*base, int*cur, intmax) { returnev_realloc (base, max*sizeof (ev_watcher_list)); }
6. 时间管理源码详解
6.1 多时间源支持
时间获取函数实现
staticev_tstampev_time (void) {#ifEV_USE_MONOTONICif (ecb_expect_true (have_monotonic)) { structtimespects; clock_gettime (CLOCK_MONOTONIC, &ts); returnts.tv_sec+ts.tv_nsec*1e-9; }#endif { structtimevaltv; gettimeofday (&tv, 0); returntv.tv_sec+tv.tv_usec*1e-6; } }
6.2 定时器管理实现
定时器插入算法
staticvoidnoinlinetimers_reify (EV_P) { EV_FREQUENT_CHECK; while (timercnt [LOW] &&ANHE_at (timerv [LOW][HEAP0]) <ev_rt_now) { ev_tstampat=ANHE_at (timerv [LOW][HEAP0]); ev_watcher_time*w= (ev_watcher_time*)ANHE_w (timerv [LOW][HEAP0]); /* 从堆中移除 */timerv [LOW][HEAP0] =timerv [LOW][--timercnt [LOW]]; downheap (timerv [LOW], LOW, HEAP0); /* 设置pending状态 */ev_at (w) =at; w->pending=1; pendings [ABSPRI (w)][w->pending-1].w= (ev_watcher*)w; pendingpri=NUMPRI; /* force recalculation */ } }
7. 跨平台适配源码
7.1 条件编译实现
平台检测和后端选择
/* ev.c中的平台适配 */#ifEV_USE_EPOLL# include"ev_epoll.c"#endif#ifEV_USE_KQUEUE# include"ev_kqueue.c"#endif#ifEV_USE_PORT# include"ev_port.c"#endif#ifEV_USE_POLL# include"ev_poll.c"#endif#ifEV_USE_SELECT# include"ev_select.c"#endif/* 默认后端选择逻辑 */staticvoid (*backend_init) (EV_P_intflags) =epoll_init;staticvoid (*backend_destroy) (EV_P) =epoll_destroy;staticvoid (*backend_poll) (EV_P_ev_tstamptimeout) =epoll_poll;staticint (*backend_check) (EV_P) =epoll_check;
7.2 系统调用封装
文件描述符操作封装
/* 跨平台fd操作 */inline_speedvoidfd_change (EV_P_intfd, intflags) { unsigned charold=anfds [fd].events; unsigned charnew=old | flags; if (ecb_expect_false (new!=old)) { anfds [fd].events=new; /* 更新backend注册 */if (old) fd_kill (EV_A_fd); if (new) fd_reify (EV_A_fd); } }
8. 调试和验证机制
8.1 数据结构完整性检查
循环不变量验证
staticvoidnoinlineecb_coldev_verify (EV_P) { inti; intfdchanged=0; assert (("libev: loop not initialized", ev_is_active (&pipe_w))); assert (("libev: loop not active", ev_active (&pipe_w) ==1)); /* 验证pending队列一致性 */for (i=NUMPRI; i--; ) { intj=0; ANPENDING*p; for (p=pendings [i]; p; p= (ANPENDING*)((ev_watcher*)p)->next) { assert (("libev: pending watcher not on pending queue", pendings [ABSPRI (p->w)][p->w->pending-1].w==p->w)); assert (("libev: pending index mismatch", p->w->pending==j+1)); ++j; } } /* 验证fd映射表 */for (i=0; i<anfdmax; ++i) { ev_watcher_list*w; for (w=anfds [i].head; w; w=w->next) { assert (("libev: inactive fd watcher on anfd list", ev_active (w) ==1)); assert (("libev: fd mismatch between watcher and anfd", ((ev_io*)w)->fd==i)); } } }
8.2 运行时调试输出
调试信息宏定义
/* 多级别调试输出 */#ifEV_DEBUG_LEVEL>0# defineEV_DBG(lvl, fmt, args...) \ do { \ if (ev_debug_level >= lvl) \ fprintf(stderr, "[libev:%d] " fmt "\n", lvl, ##args); \ } while(0)#else# defineEV_DBG(lvl, fmt, args...) do {} while(0)#endif/* 性能统计 */#ifEV_STATSVAR(unsigned int, loop_count, , , 0) // 事件循环次数VAR(unsigned int, loop_depth, , , 0) // 嵌套深度VAR(ev_tstamp, timeout_block, , , 0.) // 阻塞时间统计#endif
9. 性能优化技巧源码
9.1 分支预测优化
likely/unlikely宏应用
/* 编译器分支预测提示 */#defineecb_expect_false(expr) __builtin_expect(!!(expr), 0)#defineecb_expect_true(expr) __builtin_expect(!!(expr), 1)/* 实际应用场景 */if (ecb_expect_true (activecnt+1<1U << (sizeof (int) *8-1))) activecnt+=1;while (ecb_expect_false (loop_done)) break;
9.2 缓存友好设计
内存访问模式优化
/* 连续内存访问优化 */staticvoidfd_reify (EV_P_intfd) { /* 批量处理减少缓存未命中 */if (fdchangecnt) { /* 按顺序处理变更 */for (inti=0; i<fdchangecnt; ++i) { intfd=fdchanges [i]; // ... 处理逻辑 } fdchangecnt=0; } }
10. 源码阅读建议
10.1 阅读顺序推荐
- ev.h
– 理解API接口和数据结构 - ev_vars.h
– 掌握全局状态管理 - ev.c
– 学习核心事件循环实现 - 具体backend文件
– 理解平台适配机制 - ev++.h
– 了解C++绑定设计
10.2 关键函数追踪
ev_run() → backend_poll() → fd_event() → ev_invoke() ↓ ↓ ↓ ↓ 主循环 系统调用 事件分发 用户回调
源码版本: libev 4.33分析深度: 源码级别更新时间: 2026年3月1日
-
公众号:安全狗的自我修养
-
vx:2207344074
-
http://gitee.com/haidragon
-
http://github.com/haidragon
-
bilibili:haidragonx

夜雨聆风

