libev库源码分析系列教程(六)

admin 2026-03-05 20:40:25 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文深入剖析libev库IOWatcher的实现机制,涵盖核心设计理念、fd映射表管理、事件注册注销流程及Backend适配层实现。文章详细解析了epoll与kqueue后端的源码逻辑,阐述了事件分发、内存管理与性能优化技术,包括缓存友好设计和分支预测优化。最后总结了平台差异化处理、错误恢复机制及调试监控方法,并提供了性能优化与错误处理的最佳实践建议,适合高性能网络编程开发者参考。 综合评分: 85 文章分类: 代码审计,安全开发,安全工具


cover_image

libev库源码分析系列教程(六)

原创

haidragon haidragon

安全狗的自我修养

2026年3月4日 12:04 湖南

源码分析mettle后门工具学习 所使用的依赖库

官网:http://securitytech.cc

libev IO Watcher实现机制深度解析

1. IO Watcher核心设计

1.1 设计理念

IO Watcher采用观察者模式实现,通过文件描述符(fd)与事件类型(events)的组合来监控各种IO事件,支持边缘触发和水平触发两种模式。

1.2 数据结构定义

/* ev.h - IO Watcher定义 */typedefstruct{  EV_WATCHER(ev_io)  intfd;           /* 文件描述符 */intevents;       /* 监听事件类型(POLLIN|POLLOUT|...) */} ev_io;

2. 核心实现机制

2.1 fd映射表管理

anfds数组结构

/* ev_vars.h - 核心数据结构 */VAR(ev_watcher_list*, anfds, , , 0)    /* fd到watcher链表的映射 */VAR(int, anfdmax, , , 0)                /* anfds数组当前大小 *//* 链表节点定义 */typedefstructev_watcher_list{  EV_WATCHER_LIST;  /* 包含next/prev指针 */} ev_watcher_list;

fd到watcher的映射机制

/* 一个fd可以对应多个watcher *//* anfds[fd]指向该fd的所有watcher链表头 *//* 每个watcher通过events字段区分监听的事件类型 *//* 示例: fd=3同时监听读写事件 */anfds[3] ->ev_io(fd=3,events=POLLIN) ->ev_io(fd=3,events=POLLOUT)

2.2 事件注册与注销

启动过程源码分析

/* ev.c - ev_io_start核心实现 */voidev_io_start (EV_P_ev_io*w) {  if (ecb_expect_false (ev_is_active (w)))    return;  /* 1. 更新fd的事件掩码 */fd_change (EV_A_w->fd, w->events);     /* 2. 加入活跃watcher计数 */ev_start (EV_A_ (ev_watcher*)w, 1);     /* 3. 添加到fd对应的watcher链表 */array_add (anfds [w->fd].head, (ev_watcher_list*)w); }/* fd_change - 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;             /* 从旧状态移除 */if (old)        fd_kill (EV_A_fd);             /* 添加到新状态 */if (new)        fd_reify (EV_A_fd);     } }

停止过程源码分析

/* ev.c - ev_io_stop核心实现 */voidev_io_stop (EV_P_ev_io*w) {  /* 1. 清除pending状态 */clear_pending (EV_A_ (ev_watcher*)w);     if (ecb_expect_false (!ev_is_active (w)))    return;  /* 2. 从fd链表中移除 */array_del (anfds [w->fd].head, (ev_watcher_list*)w);     /* 3. 更新fd事件掩码 */fd_change (EV_A_w->fd, 0);     /* 4. 减少活跃计数 */ev_stop (EV_A_ (ev_watcher*)w); }

3. Backend适配层实现

3.1 epoll后端实现

epoll_ctl操作封装

/* ev_epoll.c - epoll后端核心实现 */staticvoidepoll_modify (EV_P_intfd, intoev, intnev) {  structepoll_eventev;  ev.events=0;     /* 转换libev事件类型到epoll事件类型 */if (nev&EV_READ)  ev.events |= EPOLLIN;  if (nev&EV_WRITE) ev.events |= EPOLLOUT;     ev.data.fd=fd;     if (!oev)  /* 新增 */epoll_ctl (backend_fd, EPOLL_CTL_ADD, fd, &ev);  elseif (!nev)  /* 删除 */epoll_ctl (backend_fd, EPOLL_CTL_DEL, fd, 0);  else/* 修改 */epoll_ctl (backend_fd, EPOLL_CTL_MOD, fd, &ev); }

事件轮询处理

staticvoidepoll_poll&nbsp;(EV_P_ev_tstamptimeout) { &nbsp;intres=epoll_wait&nbsp;(backend_fd,&nbsp;epoll_events,&nbsp;epoll_eventmax, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;epoll_wait_timeout&nbsp;(timeout)); &nbsp;for&nbsp;(inti=0;&nbsp;i<res;&nbsp;++i) &nbsp; &nbsp; { &nbsp; &nbsp; &nbsp;structepoll_event*e=epoll_events+i; &nbsp; &nbsp; &nbsp;intfd=e->data.fd; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;(ecb_expect_true&nbsp;(fd&nbsp;>=&nbsp;0&&fd<anfdmax&&anfds&nbsp;[fd].events)) &nbsp; &nbsp; &nbsp; &nbsp; { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;/* 将epoll事件转换回libev事件 */intrevents=0; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if&nbsp;(e->events&&nbsp;(EPOLLIN&nbsp;|&nbsp;EPOLLERR&nbsp;|&nbsp;EPOLLHUP)) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;revents&nbsp;|=&nbsp;EV_READ; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if&nbsp;(e->events&&nbsp;(EPOLLOUT&nbsp;|&nbsp;EPOLLERR&nbsp;|&nbsp;EPOLLHUP)) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;revents&nbsp;|=&nbsp;EV_WRITE; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;fd_event&nbsp;(EV_A_fd,&nbsp;revents); &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp;elsepipe_write_wanted=1;&nbsp;/* probably a pipe was closed */&nbsp; &nbsp; &nbsp;} }

3.2 kqueue后端实现

kevent操作封装

/* ev_kqueue.c - kqueue后端实现 */staticvoidkqueue_modify&nbsp;(EV_P_intfd,&nbsp;intoev,&nbsp;intnev) { &nbsp;/* 删除旧事件 */if&nbsp;(oev&EV_READ) &nbsp; &nbsp;EV_KQUEUE_MODIFY&nbsp;(fd,&nbsp;EVFILT_READ,&nbsp;EV_DELETE); &nbsp;if&nbsp;(oev&EV_WRITE) &nbsp; &nbsp;EV_KQUEUE_MODIFY&nbsp;(fd,&nbsp;EVFILT_WRITE,&nbsp;EV_DELETE); &nbsp; &nbsp; &nbsp;&nbsp;/* 添加新事件 */if&nbsp;(nev&EV_READ) &nbsp; &nbsp;EV_KQUEUE_MODIFY&nbsp;(fd,&nbsp;EVFILT_READ,&nbsp;EV_ADD); &nbsp;if&nbsp;(nev&EV_WRITE) &nbsp; &nbsp;EV_KQUEUE_MODIFY&nbsp;(fd,&nbsp;EVFILT_WRITE,&nbsp;EV_ADD); }/* kqueue事件轮询 */staticvoidkqueue_poll&nbsp;(EV_P_ev_tstamptimeout) { &nbsp;structtimespects; &nbsp;ts.tv_sec=&nbsp;(long)timeout; &nbsp;ts.tv_nsec=&nbsp;(long)((timeout-&nbsp;(long)timeout)&nbsp;*1e9); &nbsp;intres=kevent&nbsp;(backend_fd,&nbsp;0,&nbsp;0,&nbsp;kqueue_events,&nbsp;kqueue_eventmax,&nbsp;&ts); &nbsp;for&nbsp;(inti=0;&nbsp;i<res;&nbsp;++i) &nbsp; &nbsp; { &nbsp; &nbsp; &nbsp;structkevent*kev=kqueue_events+i; &nbsp; &nbsp; &nbsp;intfd=kev->ident; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;intrevents=0; &nbsp; &nbsp; &nbsp;if&nbsp;(kev->filter==EVFILT_READ) &nbsp; &nbsp; &nbsp; &nbsp;revents&nbsp;|=&nbsp;EV_READ; &nbsp; &nbsp; &nbsp;elseif&nbsp;(kev->filter==EVFILT_WRITE) &nbsp; &nbsp; &nbsp; &nbsp;revents&nbsp;|=&nbsp;EV_WRITE; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;fd_event&nbsp;(EV_A_fd,&nbsp;revents); &nbsp; &nbsp; } }

4. 事件分发机制

4.1 fd_event核心分发函数

/* ev.c - 事件分发核心 */staticvoidnoinlinefd_event_nocheck&nbsp;(EV_P_intfd,&nbsp;intrevents) { &nbsp;ev_io*w; &nbsp; &nbsp;&nbsp;/* 遍历该fd上的所有watcher */for&nbsp;(w=&nbsp;(ev_io*)anfds&nbsp;[fd].head;&nbsp;w;&nbsp;w=&nbsp;(ev_io*)((ev_watcher*)w)->next) &nbsp; &nbsp; { &nbsp; &nbsp; &nbsp;/* 检查事件匹配 */if&nbsp;(ecb_expect_true&nbsp;((ev_io*)w!=&pipe_w)) &nbsp;/* 排除内部pipe */if&nbsp;(ecb_expect_true&nbsp;(w->events&revents)) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;/* 设置pending状态并加入处理队列 */w->pending=1; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pendings&nbsp;[ABSPRI&nbsp;(w)][w->pending-1].w=&nbsp;(ev_watcher*)w; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pendingpri=NUMPRI;&nbsp;/* force recalculation */&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;} &nbsp; &nbsp; } }

4.2 批量事件处理优化

/* 事件就绪后的批量处理 */staticvoidev_invoke_pending&nbsp;(EV_P) { &nbsp;pendingpri=NUMPRI; &nbsp; &nbsp;&nbsp;while&nbsp;(pendingpri) &nbsp;/* 按优先级处理 */&nbsp; &nbsp; &nbsp;{ &nbsp; &nbsp; &nbsp;--pendingpri; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;while&nbsp;(pendings&nbsp;[pendingpri]) &nbsp; &nbsp; &nbsp; &nbsp; { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ANPENDING*p=pendings&nbsp;[pendingpri]; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;/* 移除pending状态 */p->w->pending=0; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;array_del&nbsp;(pendings&nbsp;[pendingpri],&nbsp;p); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;/* 执行用户回调 */ev_invoke&nbsp;(EV_A_p->w,&nbsp;p->events); &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; } }

5. 内存管理优化

5.1 动态数组扩容

/* anfds数组动态扩容 */staticvoid*anfds_resize&nbsp;(void*base,&nbsp;int*cur,&nbsp;intmax) { &nbsp;returnev_realloc&nbsp;(base,&nbsp;max*sizeof&nbsp;(ev_watcher_list)); }/* fd数组大小管理 */staticvoidnoinlinearray_needsize_anfd&nbsp;(void) { &nbsp;intoldmax=anfdmax; &nbsp; &nbsp;&nbsp;/* 按需扩容 */while&nbsp;(anfdmax<fdchangemax) &nbsp; &nbsp;anfdmax=anfdmax&nbsp;?&nbsp;anfdmax*2&nbsp;:&nbsp;128; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;(anfdmax>oldmax) &nbsp; &nbsp; { &nbsp; &nbsp; &nbsp;anfds=&nbsp;(ev_watcher_list*)anfds_resize&nbsp;(anfds,&nbsp;&oldmax,&nbsp;anfdmax); &nbsp; &nbsp; &nbsp;/* 初始化新分配的元素 */for&nbsp;(inti=oldmax;&nbsp;i<anfdmax;&nbsp;++i) &nbsp; &nbsp; &nbsp; &nbsp; { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;anfds&nbsp;[i].events=0; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;anfds&nbsp;[i].head=0; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; } }

5.2 链表操作优化

/* 双向链表插入 */inline_speedvoidarray_add&nbsp;(ev_watcher_list*head,&nbsp;ev_watcher_list*item) { &nbsp;item->next=head->next; &nbsp;item->prev=head; &nbsp;head->next->prev=item; &nbsp;head->next=item; }/* 双向链表删除 */inline_speedvoidarray_del&nbsp;(ev_watcher_list*head,&nbsp;ev_watcher_list*item) { &nbsp;item->prev->next=item->next; &nbsp;item->next->prev=item->prev; }

6. 性能优化技术

6.1 缓存友好设计

/* 连续内存访问优化 */VAR(int,&nbsp;fdchanges,&nbsp;[FD_CHANGES], ,&nbsp;0) &nbsp;/* fd变更缓冲区 */VAR(int,&nbsp;fdchangecnt, , ,&nbsp;0) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;/* 变更计数 *//* 批量处理fd变更 */staticvoidfd_reify&nbsp;(EV_P_intfd) { &nbsp;if&nbsp;(fdchangecnt) &nbsp; &nbsp; { &nbsp; &nbsp; &nbsp;/* 按顺序批量处理变更 */for&nbsp;(inti=0;&nbsp;i<fdchangecnt;&nbsp;++i) &nbsp; &nbsp; &nbsp; &nbsp; { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;intchfd=fdchanges&nbsp;[i]; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;/* 调用backend_modify更新注册 */backend_modify&nbsp;(EV_A_chfd, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;anfds_old&nbsp;[chfd].events, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;anfds&nbsp;[chfd].events); &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp;fdchangecnt=0; &nbsp; &nbsp; } }

6.2 分支预测优化

/* 热点路径优化 */if&nbsp;(ecb_expect_true&nbsp;(fd&nbsp;>=&nbsp;0&&fd<anfdmax&&anfds&nbsp;[fd].events)) &nbsp; { &nbsp; &nbsp;/* 常见情况: 有效fd且有待处理事件 */fd_event&nbsp;(EV_A_fd,&nbsp;revents); &nbsp; }else&nbsp; &nbsp;{ &nbsp; &nbsp;/* 异常情况: 无效fd或无事件 */pipe_write_wanted=1; &nbsp; }

7. 错误处理与恢复

7.1 fd有效性检查

/* fd事件处理前的安全检查 */staticvoidfd_event&nbsp;(EV_P_intfd,&nbsp;intrevents) { &nbsp;/* 边界检查 */if&nbsp;(ecb_expect_false&nbsp;(fd<0||fd&nbsp;>=&nbsp;anfdmax)) &nbsp; &nbsp;return; &nbsp; &nbsp; &nbsp;&nbsp;/* 事件有效性检查 */if&nbsp;(ecb_expect_false&nbsp;(!anfds&nbsp;[fd].events)) &nbsp; &nbsp;return; &nbsp; &nbsp; &nbsp;&nbsp;/* 调用实际处理函数 */fd_event_nocheck&nbsp;(EV_A_fd,&nbsp;revents); }

7.2 资源清理机制

/* 异常情况下清理fd资源 */staticvoidfd_kill&nbsp;(EV_P_intfd) { &nbsp;/* 从backend中移除 */if&nbsp;(backend_modify) &nbsp; &nbsp;backend_modify&nbsp;(EV_A_fd,&nbsp;anfds&nbsp;[fd].events,&nbsp;0); &nbsp; &nbsp; &nbsp;&nbsp;/* 清理pending状态 */for&nbsp;(ev_io*w=&nbsp;(ev_io*)anfds&nbsp;[fd].head;&nbsp;w; ) &nbsp; &nbsp; { &nbsp; &nbsp; &nbsp;ev_io*next=&nbsp;(ev_io*)((ev_watcher*)w)->next; &nbsp; &nbsp; &nbsp;if&nbsp;(w->pending) &nbsp; &nbsp; &nbsp; &nbsp; { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;clear_pending&nbsp;(EV_A_&nbsp;(ev_watcher*)w); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;w->pending=0; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp;w=next; &nbsp; &nbsp; } }

8. 平台差异化处理

8.1 Windows平台适配

#ifdef_WIN32/* Windows使用WSAEventSelect */staticvoidselect_modify&nbsp;(EV_P_intfd,&nbsp;intoev,&nbsp;intnev) { &nbsp;if&nbsp;(nev) &nbsp; &nbsp; { &nbsp; &nbsp; &nbsp;longnet_events=0; &nbsp; &nbsp; &nbsp;if&nbsp;(nev&EV_READ) &nbsp;net_events&nbsp;|=&nbsp;FD_READ&nbsp;|&nbsp;FD_ACCEPT&nbsp;|&nbsp;FD_CLOSE; &nbsp; &nbsp; &nbsp;if&nbsp;(nev&EV_WRITE)&nbsp;net_events&nbsp;|=&nbsp;FD_WRITE&nbsp;|&nbsp;FD_CONNECT&nbsp;|&nbsp;FD_CLOSE; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;WSAEventSelect&nbsp;(fd,&nbsp;backend_fd,&nbsp;net_events); &nbsp; &nbsp; } &nbsp;else&nbsp; &nbsp; &nbsp;{ &nbsp; &nbsp; &nbsp;WSAEventSelect&nbsp;(fd,&nbsp;0,&nbsp;0); &nbsp; &nbsp; } }#endif

8.2 不同后端的事件映射

/* 事件类型转换表 */staticconstintevent_map[][2]&nbsp;=&nbsp;{ &nbsp; {&nbsp;EPOLLIN, &nbsp;EV_READ&nbsp; }, &nbsp; {&nbsp;EPOLLOUT,&nbsp;EV_WRITE&nbsp;}, &nbsp; {&nbsp;EPOLLERR,&nbsp;EV_READ&nbsp;|&nbsp;EV_WRITE&nbsp;}, &nbsp; {&nbsp;EPOLLHUP,&nbsp;EV_READ&nbsp;|&nbsp;EV_WRITE&nbsp;}, &nbsp; {&nbsp;0,&nbsp;0&nbsp;} };/* 通用事件转换函数 */staticintmap_events&nbsp;(intbackend_events,&nbsp;constintmap[][2]) { &nbsp;intlibev_events=0; &nbsp;for&nbsp;(inti=0;&nbsp;map[i][0];&nbsp;++i) &nbsp; &nbsp;if&nbsp;(backend_events&map[i][0]) &nbsp; &nbsp; &nbsp;libev_events&nbsp;|=&nbsp;map[i][1]; &nbsp;returnlibev_events; }

9. 调试与监控机制

9.1 状态验证

/* IO watcher状态一致性检查 */staticvoidverify_io_watchers&nbsp;(EV_P) { &nbsp;for&nbsp;(intfd=0;&nbsp;fd<anfdmax;&nbsp;++fd) &nbsp; &nbsp; { &nbsp; &nbsp; &nbsp;if&nbsp;(anfds&nbsp;[fd].events) &nbsp; &nbsp; &nbsp; &nbsp; { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;/* 验证fd上有活跃的watcher */intfound=0; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;for&nbsp;(ev_io*w=&nbsp;(ev_io*)anfds&nbsp;[fd].head;&nbsp;w;&nbsp;w=&nbsp;(ev_io*)((ev_watcher*)w)->next) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;assert&nbsp;(("fd mismatch",&nbsp;w->fd==fd)); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;assert&nbsp;(("events mask inconsistent",&nbsp;w->events&anfds&nbsp;[fd].events)); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;found=1; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;assert&nbsp;(("no watchers found for active fd",&nbsp;found)); &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; } }

9.2 性能统计

#ifEV_STATSVAR(unsigned long,&nbsp;fd_event_count, , ,&nbsp;0) &nbsp; &nbsp; &nbsp;/* fd事件处理次数 */VAR(unsigned long,&nbsp;io_callback_count, , ,&nbsp;0) &nbsp;&nbsp;/* IO回调调用次数 */VAR(ev_tstamp,&nbsp;io_processing_time, , ,&nbsp;0.) &nbsp; &nbsp;&nbsp;/* IO处理耗时 */#endif/* 性能监控包装 */staticvoidfd_event_timed&nbsp;(EV_P_intfd,&nbsp;intrevents) {#ifEV_STATSev_tstampstart=ev_time&nbsp;();#endiffd_event_nocheck&nbsp;(EV_A_fd,&nbsp;revents);#ifEV_STATSio_processing_time+=ev_time&nbsp;()&nbsp;-start; &nbsp;++fd_event_count;#endif}

10. 最佳实践与使用建议

10.1 性能优化建议

/* 1. 合理设置fd缓存大小 */#defineFD_CHANGES&nbsp;256 &nbsp; &nbsp;/* 根据应用特点调整 */#defineANFD_INITIAL&nbsp;1024&nbsp;/* 初始fd数组大小 *//* 2. 批量操作IO watcher *//* 避免频繁的start/stop操作 *//* 3. 正确处理边缘触发 *//* 对于ET模式,需要循环读取直到EAGAIN */

10.2 错误处理模式

/* IO watcher回调中的错误处理 */staticvoidio_callback&nbsp;(EV_P_ev_io*w,&nbsp;intrevents) { &nbsp;if&nbsp;(revents&EV_ERROR) &nbsp; &nbsp; { &nbsp; &nbsp; &nbsp;/* 处理错误状态 */handle_io_error&nbsp;(w->fd); &nbsp; &nbsp; &nbsp;ev_io_stop&nbsp;(EV_A_w); &nbsp; &nbsp; &nbsp;return; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;(revents&EV_READ) &nbsp; &nbsp; { &nbsp; &nbsp; &nbsp;ssize_tn=read&nbsp;(w->fd,&nbsp;buffer,&nbsp;sizeof(buffer)); &nbsp; &nbsp; &nbsp;if&nbsp;(n>0) &nbsp; &nbsp; &nbsp; &nbsp;process_data&nbsp;(buffer,&nbsp;n); &nbsp; &nbsp; &nbsp;elseif&nbsp;(n==0) &nbsp; &nbsp; &nbsp; &nbsp; { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;/* 连接关闭 */ev_io_stop&nbsp;(EV_A_w); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;close&nbsp;(w->fd); &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp;elseif&nbsp;(errno!=EAGAIN) &nbsp; &nbsp; &nbsp; &nbsp; { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;/* 读取错误 */ev_io_stop&nbsp;(EV_A_w); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;close&nbsp;(w->fd); &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; } }

分析版本: v1.0 源码版本: libev 4.33 更新时间: 2026年3月1日

  • 公众号:安全狗的自我修养
  • vx:2207344074
  • http://gitee.com/haidragon
  • http://github.com/haidragon
  • bilibili:haidragonx

#


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:安全狗的自我修养 haidragon haidragon《libev库源码分析系列教程(六)》

评论:0   参与:  0