[libevent]event_add()
2016-07-21 15:10
239 查看
int event_add(struct event *ev, const struct timeval *tv) { struct event_base *base = ev->ev_base;//与event关联的event_base const struct eventop *evsel = base->evsel;//其实就是epoll机制(若之前选择了epoll) void *evbase = base->evbase;//其实就是epoll.c的epollop对象 int res = 0; event_debug(( "event_add: event: %p, %s%s%scall %p", ev, ev->ev_events & EV_READ ? "EV_READ " : " ", ev->ev_events & EV_WRITE ? "EV_WRITE " : " ", tv ? "EV_TIMEOUT " : " ", ev->ev_callback)); assert(!(ev->ev_flags & ~EVLIST_ALL)); /* * prepare for timeout insertion further below, if we get a * failure on any step, we should not change any state. */ if (tv != NULL && !(ev->ev_flags & EVLIST_TIMEOUT)) {//如果tv(定时)不为0则可能是定时事件,需要预先为小根堆分配足够的空间 if (min_heap_reserve(&base->timeheap, 1 + min_heap_size(&base->timeheap)) == -1) return (-1); /* ENOMEM == errno */ } if ((ev->ev_events & (EV_READ|EV_WRITE|EV_SIGNAL)) &&//如何是读写信号事件,并且还没有插入到任何链表,则调用epoll_add,并且插入到事件链表 !(ev->ev_flags & (EVLIST_INSERTED|EVLIST_ACTIVE))) { res = evsel->add(evbase, ev); if (res != -1) event_queue_insert(base, ev, EVLIST_INSERTED); } /* * we should change the timout state only if the previous event * addition succeeded. */ if (res != -1 && tv != NULL) { struct timeval now; /* * we already reserved memory above for the case where we * are not replacing an exisiting timeout. */ if (ev->ev_flags & EVLIST_TIMEOUT)//如何事件之前已到时则需要移除,后面才能重新插入 event_queue_remove(base, ev, EVLIST_TIMEOUT); /* Check if it is active due to a timeout. Rescheduling * this timeout before the callback can be executed * removes it from the active list. */ if ((ev->ev_flags & EVLIST_ACTIVE) &&//由于定时事件到时并且已经插入到就绪链表,移除并中断它的回调函数 (ev->ev_res & EV_TIMEOUT)) { /* See if we are just active executing this * event in a loop */ if (ev->ev_ncalls && ev->ev_pncalls) { /* Abort loop */ *ev->ev_pncalls = 0; } event_queue_remove(base, ev, EVLIST_ACTIVE); } gettime(base, &now);//得到现在的时间 evutil_timeradd(&now, tv, &ev->ev_timeout);//将event的ev_timeout设置成到期的时间,即现在时间加上定时的时间 event_debug(( "event_add: timeout in %ld seconds, call %p", tv->tv_sec, ev->ev_callback)); event_queue_insert(base, ev, EVLIST_TIMEOUT);//插入到小根堆里面去 } return (res); }
相关文章推荐
- libevent库的使用--定时器的使用实例
- Linux下编译安装php libevent扩展实例
- libevent 一个简单的event示例
- libevent 初始化与event_init
- libevent event_set函数与event_add函数解析 [SYM]
- libevent2 bufferevent应用示例
- libevent 介绍
- libevent代码结构
- libevent 的Reactor模型
- libevent -简单的异步IO介绍
- 【网游服务器】Linux下libevent安装与示例
- 后续博客的方向
- 静态编译libevent
- libevent源码分析之 tail queue
- Linux下定时器的使用
- libevent安装与libevent定时器
- Archlinux使用最新版goagent的几点注意(无法上传问题)
- cocos2dx加libevent库
- libevent中evbuffer简单使用
- libevent 中bufferevent_setcb 之writecb 使用