libevent源码分析--event_set()函数

如果按照正常使用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; }

min_heap_idx和ev_timeout,如果是timeout事件,他们是event在小根堆中的索引和超时值,libevent使用小根堆来管理定时事件。这里先不用理解。

下面一个函数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即可。

你可能感兴趣的:(libevent)