libevent---核心event和event_base

结构体event和event_base是libevent的两个核心数据结构,前者代表一个事件对象,后者代表整个事件处理框架。

1.event事件对象

//event.h
struct event {
TAILQ_ENTRY (event) ev_next;          //已注册事件链表
TAILQ_ENTRY (event) ev_active_next;//就绪事件链表
TAILQ_ENTRY (event) ev_signal_next; //signal链表
unsigned int min_heap_idx;    /* for managing timeouts,事件在堆中的下标 */

struct event_base *ev_base;

int ev_fd;      //对于I/O事件,是绑定的文件描述符;对于signal事件,是绑定的信号
short ev_events; //event关注的事件类型
short ev_ncalls; //事件就绪执行时,调用 ev_callback 的次数
short *ev_pncalls;    /* Allows deletes in callback */

struct timeval ev_timeout;  //timout事件的超时值

int ev_pri;   /* smaller numbers are higher priority,优先级 */

void (*ev_callback)(int, short, void *arg); //回调函数
void *ev_arg; //回调函数的参数

int ev_res;        /* result passed to event callback */
int ev_flags; //event的状态
};
Libevent通过event对象将I/O事件、信号事件和定时器事件封装,从而统一处理,这也是libevent的精妙所有。
各个字段的具体含义:
(1) ev_events:event关注的事件类型,它可以是以下3种类型: 
I/O事件: EV_WRITE和EV_READ 
定时事件:EV_TIMEOUT 
信号:    EV_SIGNAL 
辅助选项:EV_PERSIST,表明是一个永久事件 
libevent中的定义为:
#define EV_TIMEOUT    0x01
#define EV_READ    0x02
#define EV_WRITE    0x04
#define EV_SIGNAL    0x08
#define EV_PERSIST    0x10    /* Persistant 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指向事件框架实例。
(5)ev_fd,对于 I/O事件,是绑定的文件描述符;对于 signal 事件,是事件对应的信号;
(6)eb_flags:libevent 用于标记 event信息的字段,表明事件当前的状态,可能的值有:
#define EVLIST_TIMEOUT   0x01 // event在time堆中 
#define EVLIST_INSERTED 0x02 // event在已注册事件链表中 
#define EVLIST_SIGNAL    0x04 // 未见使用 
#define EVLIST_ACTIVE    0x08 // event在激活链表中 
#define EVLIST_INTERNAL 0x10 // 内部使用标记 
#define EVLIST_INIT      0x80 // event 已被初始化


2.event_base(事件处理框架)

//evenet_internal.h
struct event_base {
const struct eventop *evsel; //底层具体I/O demultiplex操作函数集
void *evbase;
int event_count;        /* counts number of total events,总的事件数量 */
int event_count_active;    /* counts number of active events,就绪事件数量 */

int event_gotterm;        /* Set to terminate loop */
int event_break;        /* Set to terminate loop immediately */

/* active event management */
//就绪事件链表数组
struct event_list **activequeues;
int nactivequeues;//就绪事件队列个数

/* signal handling info */
struct evsignal_info sig; //用于管理信号

struct event_list eventqueue; //注册事件队列
struct timeval event_tv;

struct min_heap timeheap; //管理定时器的小根堆
struct timeval tv_cache; //记录时间缓存
};
(1)evsel:libevent支持Linux、Windows等多种平台,也支持epoll、poll、select、kqueue等多种I/O多路复用模型。如果把event_init、event_add看成高层抽象的统一事件操作接口,则evsel为这些函数在底层具体的I/O demultiplex的对应的操作函数集。eventop为函数指针的集合:

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;
};
在初始化函数event_base_new中,libevent将evsel指向全局数组eventops的具体元素:

I/O multiplex机制实例数组
static const struct eventop *eventops[] = {
#ifdef HAVE_EVENT_PORTS
&evportops,
#endif
#ifdef HAVE_WORKING_KQUEUE
&kqops,
#endif
#ifdef HAVE_EPOLL
&epollops,
#endif
#ifdef HAVE_DEVPOLL
&devpollops,
#endif
#ifdef HAVE_POLL
&pollops,
#endif
#ifdef HAVE_SELECT
&selectops,
#endif
#ifdef WIN32
&win32ops,
#endif
NULL
};



你可能感兴趣的:(数据结构,class,io,heap,struct)