1.event_base结构体在event_internal.h中:
2.代码
struct event_base {
const struct eventop *evsel; /*指向eventop结构体的指针,它的作用是在初始的选择一种后端的I/O复用机制。*/
void *evbase;/*实际执行操作,它由evsel->init()初始化*/
struct event_changelist changelist;
const struct eventop *evsigsel;/*指向信号的后端处理机制*/
struct evsig_info sig;/*信号事件处理器使用的数据结构,其中封装了一个由socketpair创建的管道,它用于信号处理函数和事件多路分发器之间的通信*/
int virtual_event_count;//虚拟事件数量
int event_count; //所有事件数量
int event_count_active; //激活事件数量
int event_gotterm;//是否执行完活动事件队列上的任务之后退出事件循环
int event_break; //是否立即退出事件循环。
int event_continue;//是否应该启动一个新的事件循环
int event_running_priority;//目前正在处理活动事件队列的优先级
int running_loop;//事件循环是否启动
struct event_list *activequeues;//存放被激活的事件,这是一个队列数组或者说是队列的链表,具有相同优先级的被激活事件存放在同一个队列中,不同优先级的事件存放在不同的队列中;
int nactivequeues;//event_base中一共有nactivequeues个不同优先级的活动事件队列。
//管理时间的
struct common_timeout_list **common_timeout_queues;
int n_common_timeouts;
int n_common_timeouts_allocated;
struct deferred_cb_queue defer_queue;//存放延迟调用的回调函数,对于每一次的轮询,只有当所有的已激活的事件都被处理了之后,这些回调函数才会被处理。
struct event_io_map io;//IO事件与IO事件处理器的映射关系
struct event_signal_map sigmap;//信号事件与信号事件处理器的映射关系
struct event_list eventqueue;//存放所有的注册事件,不论是IO事件,定时器事件还是信号事件,只要注册了,都放在这个队列里。
struct timeval event_tv;
struct min_heap timeheap;//小根堆,存放超时事件。
struct timeval tv_cache;
#if defined(_EVENT_HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
struct timeval tv_clock_diff;
time_t last_updated_clock_diff;
#endif
//下面是多线程支持。
#ifndef _EVENT_DISABLE_THREAD_SUPPORT
unsigned long th_owner_id;
void *th_base_lock;
struct event *current_event;
void *current_event_cond;
int current_event_waiters;
#endif
#ifdef WIN32
/** IOCP support structure, if IOCP is enabled. */
struct event_iocp_port *iocp;
#endif
enum event_base_config_flag flags;
int is_notify_pending;
evutil_socket_t th_notify_fd[2];
struct event th_notify;
int (*th_notify_fn)(struct event_base *base);
};
3.eventop结构体定义如下: 在event-internal.h中定义
eventop结构体封装了IO复用机制必要的操作;
它为event_base支持的所有后端IO复用机制提供了一个统一的接口;
struct eventop {
const char *name; ====>IO复用机制的名称。
void *(*init)(struct event_base *); //初始化函数
int (*add)(struct event_base *, evutil_socket_t fd, short old, short events, void *fdinfo);
int (*del)(struct event_base *, evutil_socket_t fd, short old, short events, void *fdinfo);
int (*dispatch)(struct event_base *, struct timeval *);
void (*dealloc)(struct event_base *); =====>注销,释放资源
int need_reinit; ======>程序fork()之后是否需要重新初始化event_base
enum event_method_feature features; ====>/*
IO复用技术支持的一些特性,下面有三个可选值:
EV_FEATURE_ET = 0x01,支持边沿触发事件
EV_FEATURE_O1 = 0x02,事件检查算法的复杂度是0(1)
EV_FEATURE_FDS = 0x04不仅能监听socket上的事件,还能监听其他类型的文件描述符上的事件
*/
size_t fdinfo_len; ============>/*
有的io复用机制需要为每个io事件队列和信号事件队列分配额外的内存
一避免同一个文件描述符被重复插入io复用机制的事件表中
下面这个字段指定了这段内存的长度
*/
};