Libevent源码分析—event_set()
初始化完event_base后,下面要初始化event,通过调用event_set()实现 。相关源码位于event.c
event_set()
void event_set(struct event *ev, int fd, short events, void (*callback)(int, short, void *), void *arg) { /* Take the current base - caller needs to set the real base later */ ev->ev_base = current_base; //设置event属于当前base;current_base通过event_init()设置 ev->ev_callback = callback; //设置回调函数 ev->ev_arg = arg; //设置回调函数的3个参数 ev->ev_fd = fd; ev->ev_events = events; ev->ev_res = 0; ev->ev_flags = EVLIST_INIT; //设置event状态 ev->ev_ncalls = 0; ev->ev_pncalls = NULL; min_heap_elem_init(ev); //初始化event在小根堆中索引为-1 min_heap.h /* by default, we put new events into the middle priority */ if(current_base) ev->ev_pri = current_base->nactivequeues/2; //设置event优先级 }
通过传入的参数:fd, events, 回调函数,arg设置event的相应成员,并初始化event在小根堆中的索引为-1,以及设置event的优先级。
接下来调用event_base_set()设置event所属的event_base。
其实在event_set()中已经将event所属的event_base设置为当前的current_base,而current_base在event_init()中被赋值为新建的event_base。所以,如果要将一个新的event捆绑的event_base设置为新建的event_base,则可以不需要event_base_set()这步调用。如果有多个event_base,则才需要这步;就一个event_base时,是不需要这步的,因为此时current_base就等于event_base。
event_base_set()
int event_base_set(struct event_base *base, struct event *ev) { /* Only innocent events may be assigned to a different base */ if (ev->ev_flags != EVLIST_INIT) //只能对新建的event设置其所属event_base return (-1); ev->ev_base = base; //设置所属event_base ev->ev_pri = base->nactivequeues/2; //设置优先级 return (0); }
由上面代码可看到,只能对新建的状态为EVLIST_INIT的event设置所属event_base
event有优先级,我们还可以单独调用下面的函数来专门设置event的优先级,但要求不能对活跃的event设置。
event_priority_set()
int event_priority_set(struct event *ev, int pri) { if (ev->ev_flags & EVLIST_ACTIVE) //不能对活跃的event设置优先级 return (-1); if (pri < 0 || pri >= ev->ev_base->nactivequeues) return (-1); ev->ev_pri = pri; //设置优先级 return (0); }
脚踏实地、积极思考