您的位置:首页 > 其它

[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