码迷,mamicode.com
首页 > 其他好文 > 详细

libEvent结构体介绍

时间:2015-08-11 09:55:15      阅读:174      评论:0      收藏:0      [点我收藏+]

标签:

1 event_base

01.struct event_base { 

02. const struct eventop *evsel; 

03. void *evbase;  

04. int event_count;   

05. int event_count_active;  

06. int event_gotterm;   

07. int event_break;   

08. // active event management

09. struct event_list **activequeues; 

10. int nactivequeues; 

11. // signal handling info 

12. struct evsignal_info sig; 

13. struct event_list eventqueue; 

14. struct timeval event_tv; 

15. struct min_heap timeheap; 

16. struct timeval tv_cache; 

17.}; 

 

 

1)evsel和evbase这两个字段的设置可能会让人有些迷惑,这里你可以把evsel和evbase看作是类和静态函数的关系,比如添加事件时的调用行为:evsel->add(evbase, ev),实际执行操作的是evbase;

这相当于class::add(instance, ev),instance就是class的一个对象实例。evsel指向了全局变量static const struct eventop *eventops[]中的一个;

前面也说过,libevent将系统提供的I/O demultiplex机制统一封装成了eventop结构;

因此eventops[]包含了select、poll、kequeue和epoll等等其中的若干个全局实例对象。 evbase实际上是一个eventop实例对象;

先来看看eventop结构体,它的成员是一系列的函数指针, 在event-internal.h文件中:

struct eventop {  

const char *name;  

void *(*init)(struct event_base *); // 初始化  

int (*add)(void *, struct event *); // 注册事件  

int (*del)(void *, struct event *); // 删除事件  

int (*dispatch)(struct event_base *, void *, struct timeval *); // 事件分发  

void (*dealloc)(struct event_base *, void *); // 注销,释放资源  

// set if we need to reinitialize the event base   

int need_reinit;

};

也就是说,在libevent中,每种I/O demultiplex机制的实现都必须提供这五个函数接口,来完成自身的初始化、销毁释放;对事件的注册、注销和分发。比如对于epoll,libevent实现了5个对应的接口函数,并在初始化时并将eventop的5个函数指针指向这5个函数,那么程序就可以使用epoll作为I/O demultiplex机制了,这个在后面会再次提到。

2)activequeues是一个二级指针,前面讲过libevent支持事件优先级,因此你可以把它看作是数组,其中的元素activequeues[priority]是一个链表,链表的每个节点指向一个优先级为priority的就绪事件event。

3)eventqueue,链表,保存了所有的注册事件event的指针。

4)sig是由来管理信号的结构体,将在后面信号处理时专门讲解;

5)timeheap是管理定时事件的小根堆,将在后面定时事件处理时专门讲解;

6)event_tv和tv_cache是libevent用于时间管理的变量,将在后面讲到;  其它各个变量都能因名知意,就不再啰嗦了。

 

2 event

01.struct event { 

02. TAILQ_ENTRY (event) ev_next; 

03. TAILQ_ENTRY (event) ev_active_next; 

04. TAILQ_ENTRY (event) ev_signal_next; 

05. unsigned int min_heap_idx;  

06. struct event_base *ev_base; 

07. int ev_fd; 

08. short ev_events; 

09. short ev_ncalls; 

10. short *ev_pncalls;  

11. struct timeval ev_timeout; 

12. int ev_pri;   

13. void (*ev_callback)(int, short, void *arg); 

14. void *ev_arg; 

15. int ev_res;   

16. int ev_flags; 

17.}; 

1)ev_events:event关注的事件类型,它可以是以下3种类型: I/O事件: EV_WRITE和EV_READ 定时事件:EV_TIMEOUT 信号: EV_SIGNAL 辅助选项:EV_PERSIST,表明是一个永久事件,如果没有此类型,那么event只被触发一次。

2)ev_next,ev_active_next和ev_signal_next都是双向链表节点指针;它们是libevent对不同事件类型和在不同的时期,对事件的管理时使用到的字段。

libevent使用双向链表保存所有注册的I/O和Signal事件,ev_next就是该I/O事件在链表中的位置;称此链表为“已注册事件链表“;同样ev_signal_next就是signal事件在signal事件链表中的位置;  ev_active_next:libevent将所有的激活事件放入到链表active list中,然后遍历active list执行调度,ev_active_next就指明了event在active list中的位置;  

3)min_heap_idx和ev_timeout,如果是timeout事件,它们是event在小根堆中的索引和超时值,libevent使用小根堆来管理定时事件,这将在后面定时事件处理时专门讲解 4)ev_base该事件所属的反应堆实例,这是一个event_base结构体,下一节将会详细讲解;

5)ev_fd,对于I/O事件,是绑定的文件描述符;对于signal事件,是绑定的信号;

6)ev_callback,event的回调函数,被ev_base调用,执行事件处理程序,这是一个函数指针,原型为: void (*ev_callback)(int fd, short events, void *arg) 其中参数fd对应于ev_fd;events对应于ev_events;arg对应于ev_arg;

7)ev_arg:void*,表明可以是任意类型的数据,在设置event时指定;

8)eb_flags:libevent用于标记event信息的字段,表明其当前的状态,可能的值有:

9)ev_ncalls:事件就绪执行时,调用ev_callback的次数,通常为1;

10)ev_pncalls:指针,通常指向ev_ncalls或者为NULL;

11)ev_res:记录了当前激活事件的类型;

 

libEvent结构体介绍

标签:

原文地址:http://www.cnblogs.com/improvement/p/4720083.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!