如果按照正常使用libevent库的流程来说,首先调用event_init()函数,然后调用event_set()函数,然后event_add()函数,然后是event_dispatch()函数。
1、event_init() 创建一个event_base对象也就是创建一个新的libevent实例,该函数同时还堆新生成的libevent实例进行了初始化。首先为event_base实例申请了空间,然后初始化timer mini_heap。选择并初始化合适的系统i/o的复用机制,初始化各个事件链表,还检测了系统的时间设置,为后面的时间管理打下基础。
2、event_set() 向libevent添加一个事件,需要首先设置event对象,这通过调用一系列的函数实现:event_set() event_base_set() event_priority_set()
3、event_add() 后文介绍
4、event_base_loop() 后文介绍
event_set(struct event *ev,int fd,short events,void(*callback)(int,short,void),void * arg);
设置事件ev绑定的文件描述符或者信号,对于定时事件,设为-1即可,
设置事件类型,比如EV_READ}EV_PERSIST,EV_WRITE,EV_SIGNAL等
设置事件的回调函数以及参数arg
初始化其他字段,比如缺省的event_base和优先级。
void 635 event_set(struct event *ev, int fd, short events, 636 void (*callback)(int, short, void *), void *arg) 637 { 638 /* Take the current base - caller needs to set the real base later */ 639 ev->ev_base = current_base; 640 641 ev->ev_callback = callback; 642 ev->ev_arg = arg; 643 ev->ev_fd = fd; 644 ev->ev_events = events; 645 ev->ev_res = 0; 646 ev->ev_flags = EVLIST_INIT; 647 ev->ev_ncalls = 0; 648 ev->ev_pncalls = NULL; 649 650 min_heap_elem_init(ev); 651 652 /* by default, we put new events into the middle priority */ 653 if(current_base) 654 ev->ev_pri = current_base->nactivequeues/2; 655 }这里主要是初始化了关于event的一些列的东西,ev_base默认是系统的current_base,然后回调函数设置时传递的参数,这个event的参数ev_arg,这些所有的初始化,基本上完成了以一个event所需的主要字段,在event_base_set()函数中,知识重复了上面的几个字段,因为可以通过event_base_set函数可以修改这个event所属的event_base。
int 658 event_base_set(struct event_base *base, struct event *ev) 659 { 660 /* Only innocent events may be assigned to a different base */ 661 if (ev->ev_flags != EVLIST_INIT) 662 return (-1); 663 664 ev->ev_base = base; 665 ev->ev_pri = base->nactivequeues/2; 666 667 return (0); 668 }654行是在默认情况下,讲这个event的优先级设置为中间的级别,其中主要的一部分是650行的min_heap_elem_init()函数。但是这个函数很简单:
void min_heap_elem_init(struct event* e) { e->min_heap_idx = -1; }
下面一个函数event_priority_set()函数:
/* 671 * Set's the priority of an event - if an event is already scheduled 672 * changing the priority is going to fail. 673 */ 674 675 int 676 event_priority_set(struct event *ev, int pri) 677 { 678 if (ev->ev_flags & EVLIST_ACTIVE) 679 return (-1); 680 if (pri < 0 || pri >= ev->ev_base->nactivequeues) 681 return (-1); 682 683 ev->ev_pri = pri; 684 685 return (0); 686 }但是要注意的是上面的注释,如果这个event已经被放到队列中,那么这样的修改处出现错误,这个函数的调用只用在一个调用时刻,在event_set函数之后,在event_add函数之前。这是关于设置event的几个函数,一般在初始化之后调用一个event_set即可。