目录
创建自定义event_base——event_base_new_with_config
以下源码均基于libevent-2.0.21-stable。
前言
要实现libevent的事件处理,最关键的就是event_base,event_base就像是一棵树,而需要进行处理的事件event就像是树上的果子,因此,在分析libevent的事件处理之前,先来分析一下event_base。
由于event_base结构体中包含了三十多个成员,直接去分析每个成员是比较麻烦并且没有太大意义的,因此个人觉得从event_base的使用中去了解event_base各个结构体成员的作用会比较好,因此这里先来看看event_base的创建。
创建默认的event_base
在event.c中,可以看到event_base有两种创建方式。
目前最常用的一种方式是使用event_base_new,该函数的定义如下:
struct event_base *
event_base_new(void)
{
struct event_base *base = NULL;
struct event_config *cfg = event_config_new();
if (cfg) { //cfg非空,说明event_config分配成功
base = event_base_new_with_config(cfg); //将cfg配置到base中去
event_config_free(cfg); //清空cfg链表
}
return base;
}//event.c
可以发现,该函数是创建了一个event_base并最终返回了它,并且该函数无需传入任何参数,也就是说,如果调用该函数来创建一个event_base,那么返回得到的就是一个默认的base,而event_base_new也就是默认的event_base创建函数。关于其中使用到的event_config相关的函数,下面会分析。
除了这种创建方式外,还有另一种创建方式event_init,该函数声明如下:
/**
Initialize the event API.
The event API needs to be initialized with event_init() before it can be
used. Sets the global current base that gets used for events that have no
base associated with them.
@deprecated This function is deprecated because it replaces the "current"
event_base, and is totally unsafe for multithreaded use. The replacement
is event_base_new().
@see event_base_set(), event_base_new()
*/
struct event_base *event_init(void);//event.h
首先关注到该函数定义的描述文字中有一个@deprecated,这说明该函数是不推荐使用并且有替代品的。并提到该函数不是线程安全的,替代函数就是event_base_new。来看看该函数定义:
struct event_base *
event_init(void)
{
struct event_base *base = event_base_new_with_config(NULL); //默认方式创建一个base 相当于调用了一个event_base_new
if (base == NULL) {
event_errx(1, "%s: Unable to construct event_base", __func__);
return NULL;
}
current_base = base;
return (base);
}
在event_init函数中,创建一个新的event_base是用NULL为参数调用event_base_new_with_config的,这实际上就相当于调用了默认的event_base_new。并且在最后用current_base来保存新创建的event_base,这里的current_base是一个全局变量,这也是导致该函数线程不安全的原因。查看了一下其他资料,提到event_init实际上是老版本libevent中使用到的创建函数,不过现在相当于被废弃了,只不过为了兼容低版本,还依然保存着。
这里分析了创建一个默认的event_base,那么如果创建一个自定义的event_base呢?并且自定义的event_base中有哪些属性是可以自定义的呢?
event_base的配置
创建一个自定义的event_base是通过函数event_base_new_with_config来实现的,该函数声明如下:
struct event_base *event_base_new_with_config(const struct event_config *);
该函数需要传入一个event_config参数,而该参数则包含了用户自定义的配置信息&#