[libevent]event_add()

来源:互联网 发布:into you mac miller 编辑:程序博客网 时间:2024/06/08 03:31
intevent_add(struct event *ev, const struct timeval *tv){struct event_base *base = ev->ev_base;//与event关联的event_baseconst 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);}

0 0
原创粉丝点击