前言 : Libevent 的核心是事件驱动、同步非阻塞,为了达到这一目标,必须使用系统提供的 I/O 多路复用技术。而这些在不同的平台上却各有不同。
1 统一的关键
Libevent 支持多种 I/O 多路复用技术的关键就在于结构体 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 *) // 注销,释放资源
int need_reinit;
};
2 设置 I/O demultiplex 机制
Libevent 把所有支持的 I/O demultiplex 机制存储在一个全局静态数组 eventops 中,并在初始化时,选择使用何种机制,数组内容根据优先级顺序声明如下;
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
};
然后 Libevent 根据系统配置和编译选项决定使用哪一种 I/O demultiplex 机制,在函数 event_base_new()中实现 ;
base -> evbase = NULL;
for( i = 0; eventops[i] &&!base -> evbase; i++)
{
base -> evsel = eventops[i];
base -> evbase = base -> evsel -> init(base);
}
可以看出 Libevent 在编译阶段选择系统的 I/O demultiplex 机制,而不支持在运行阶段根据配置再次选择