一、事件类型 event-internal.h
/**
* @name event flags
*
* Flags to pass to event_new(), event_assign(), event_pending(), and
* anything else with an argument of the form "short events"
*/
/**@{*/
/** Indicates that a timeout has occurred. It's not necessary to pass
* this flag to event_for new()/event_assign() to get a timeout. */
// 定时事件
#define EV_TIMEOUT 0x01
/** Wait for a socket or FD to become readable */
// 读事件
#define EV_READ 0x02
/** Wait for a socket or FD to become writeable */
// 写事件
#define EV_WRITE 0x04
/** Wait for a POSIX signal to be raised*/
// 信号
#define EV_SIGNAL 0x08
/**
* Persistent event: won't get removed automatically when activated.
*
* When a persistent event with a timeout becomes activated, its timeout
* is reset to 0.
*/
// 永久事件,激活执行后会重新加到队列中等待下一次激活,否则激活执行后会自动移除
#define EV_PERSIST 0x10
/** Select edge-triggered behavior, if supported by the backend. */
// 边沿触发,一般需要后台方法支持
#define EV_ET 0x20
/**
* If this option is provided, then event_del() will not block in one thread
* while waiting for the event callback to complete in another thread.
*
* To use this option safely, you may need to use event_finalize() or
* event_free_finalize() in order to safely tear down an event in a
* multithreaded application. See those functions for more information.
*
* THIS IS AN EXPERIMENTAL API. IT MIGHT CHANGE BEFORE THE LIBEVENT 2.1 SERIES
* BECOMES STABLE.
**/
// 终止事件,如果设置这个选项,则event_del不会阻塞,需要使用event_finalize或者
// event_free_finalize以保证多线程安全
#define EV_FINALIZE 0x40
/**
* Detects connection close events. You can use this to detect when a
* connection has been closed, without having to read all the pending data
* from a connection.
*
* Not all backends support EV_CLOSED. To detect or require it, use the
* feature flag EV_FEATURE_EARLY_CLOSE.
**/
// 检查事件连接是否关闭;可以使用这个选项来检测链接是否关闭,而不需要读取此链接所有未决数据;
#define EV_CLOSED 0x80
二、事件状态标志 event_struct.h中
// 事件在time min_heap堆中
#define EVLIST_TIMEOUT 0x01
// 事件在已注册事件链表中
#define EVLIST_INSERTED 0x02
// 目前未使用
#define EVLIST_SIGNAL 0x04
// 事件在激活链表中
#define EVLIST_ACTIVE 0x08
// 内部使用标记
#define EVLIST_INTERNAL 0x10
// 事件在下一次激活链表中
#define EVLIST_ACTIVE_LATER 0x20
// 事件已经终止
#define EVLIST_FINALIZING 0x40
// 事件初始化完成,但是哪儿都不在
#define EVLIST_INIT 0x80
// 包含所有事件状态,用于判断合法性的
#define EVLIST_ALL 0xff
三、后台方法 event.c
/* Array of backends in order of preference. */
后台方法的全局静态数组
static const struct eventop *eventops[] = {
#ifdef EVENT__HAVE_EVENT_PORTS
&evportops,
#endif
#ifdef EVENT__HAVE_WORKING_KQUEUE
&kqops,
#endif
#ifdef EVENT__HAVE_EPOLL
&epollops,
#endif
#ifdef EVENT__HAVE_DEVPOLL
&devpollops,
#endif
#ifdef EVENT__HAVE_POLL
&pollops,
#endif
#ifdef EVENT__HAVE_SELECT
&selectops,
#endif
#ifdef _WIN32
&win32ops,
#endif
NULL
};
四、后台方法特征列表 event.h
/**
A flag used to describe which features an event_base (must) provide.
Because of OS limitations, not every Libevent backend supports every
possible feature. You can use this type with
event_config_require_features() to tell Libevent to only proceed if your
event_base implements a given feature, and you can receive this type from
event_base_get_features() to see which features are available.
*/
// 用来描述event_base必须提供的特征值,其实是后台方法提供的;
// 因为OS的限制,不是所有event_base后台方法都支持每个可能的特征;
// 必须使用event_config_require_features()进行配置,同时必须使用
// event_base_get_features()查看是否支持配置的特征。
enum event_method_feature {
/** Require an event method that allows edge-triggered events with EV_ET. */
// 边沿触发,高效但是容易丢消息,注意与水平触发区分
EV_FEATURE_ET = 0x01,
/** Require an event method where having one event triggered among
* many is [approximately] an O(1) operation. This excludes (for
* example) select and poll, which are approximately O(N) for N
* equal to the total number of possible events. */
// 要求具有很多事件的后台方法可以以近似O(1)处理事件;select和poll
// 无法提供这种特征,它们只能提供近似O(N)的操作
EV_FEATURE_O1 = 0x02,
/** Require an event method that allows file descriptors as well as
* sockets. */
// 后台方法可以处理包括sockets在内的各种文件描述符
EV_FEATURE_FDS = 0x04,
/** Require an event method that allows you to use EV_CLOSED to detect
* connection close without the necessity of reading all the pending data.
*
* Methods that do support EV_CLOSED may not be able to provide support on
* all kernel versions.
**/
// 要求后台方法可以使用EV_CLOSED检测链接关闭,而不需要读完所有未决数据才能判断
// 支持EV_CLOSED的后台方法不是所有OS内核都支持的
EV_FEATURE_EARLY_CLOSE = 0x08
};
五、event_base或者libevent工作模式 event.h
/**
A flag passed to event_config_set_flag().
These flags change the behavior of an allocated event_base.
@see event_config_set_flag(), event_base_new_with_config(),
event_method_feature
*/
// 可以使用event_config_set_flag设置以下配置。
// 这个配置可以改变event_base的行为
enum event_base_config_flag {
/** Do not allocate a lock for the event base, even if we have
locking set up.
Setting this option will make it unsafe and nonfunctional to call
functions on the base concurrently from multiple threads.
*/
// 非阻塞模式,多线程不安全
EVENT_BASE_FLAG_NOLOCK = 0x01,
/** Do not check the EVENT_* environment variables when configuring
an event_base */
// 这种模式下不再检查EVENT_*环境变量
EVENT_BASE_FLAG_IGNORE_ENV = 0x02,
/** Windows only: enable the IOCP dispatcher at startup
If this flag is set then bufferevent_socket_new() and
evconn_listener_new() will use IOCP-backed implementations
instead of the usual select-based one on Windows.
*/
// 只应用于windows环境
EVENT_BASE_FLAG_STARTUP_IOCP = 0x04,
/** Instead of checking the current time every time the event loop is
ready to run timeout callbacks, check after each timeout callback.
*/
// 每次event_loop准备运行timeout回调时,不再检查当前的时间,而是
// 在每次timeout回调之后检查
EVENT_BASE_FLAG_NO_CACHE_TIME = 0x08,
/** If we are using the epoll backend, this flag says that it is
safe to use Libevent's internal change-list code to batch up
adds and deletes in order to try to do as few syscalls as
possible. Setting this flag can make your code run faster, but
it may trigger a Linux bug: it is not safe to use this flag
if you have any fds cloned by dup() or its variants. Doing so
will produce strange and hard-to-diagnose bugs.
This flag can also be activated by setting the
EVENT_EPOLL_USE_CHANGELIST environment variable.
This flag has no effect if you wind up using a backend other than
epoll.
*/
// 如果后台方法是epoll,则此模式是指可以安全的使用libevent内部changelist
// 进行批量增删而尽可能减少系统调用。这种模式可以让代码性能更高,
// 但是可能会引起Linux bug:如果有任何由dup()或者他的变量克隆的fds,
// 则是不安全的。这样做会引起奇怪并且难以检查的bugs。此模式可以通过
// EVENT_EPOLL_USE_CHANGELIST环境变量激活。
// 此模式只有在使用epoll时可用
EVENT_BASE_FLAG_EPOLL_USE_CHANGELIST = 0x10,
/** Ordinarily, Libevent implements its time and timeout code using
the fastest monotonic timer that we have. If this flag is set,
however, we use less efficient more precise timer, assuming one is
present.
*/
// 通常情况下,libevent使用最快的monotonic计时器实现自己的计时和超时控制;
// 此模式下,会使用性能较低但是准确性更高的计时器。
EVENT_BASE_FLAG_PRECISE_TIMER = 0x20
};
六、事件关闭时的回调函数模式类型
/** @name Event closure codes
Possible values for evcb_closure in struct event_callback
@{
*/
/** A regular event. Uses the evcb_callback callback */
// 常规事件,使用evcb_callback回调
#define EV_CLOSURE_EVENT 0
/** A signal event. Uses the evcb_callback callback */
// 信号事件;使用evcb_callback回调
#define EV_CLOSURE_EVENT_SIGNAL 1
/** A persistent non-signal event. Uses the evcb_callback callback */
// 永久性非信号事件;使用evcb_callback回调
#define EV_CLOSURE_EVENT_PERSIST 2
/** A simple callback. Uses the evcb_selfcb callback. */
// 简单回调,使用evcb_selfcb回调
#define EV_CLOSURE_CB_SELF 3
/** A finalizing callback. Uses the evcb_cbfinalize callback. */
// 结束的回调,使用evcb_cbfinalize回调
#define EV_CLOSURE_CB_FINALIZE 4
/** A finalizing event. Uses the evcb_evfinalize callback. */
// 结束事件回调,使用evcb_evfinalize回调
#define EV_CLOSURE_EVENT_FINALIZE 5
/** A finalizing event that should get freed after. Uses the evcb_evfinalize
* callback. */
// 结束事件之后应该释放,使用evcb_evfinalize回调
#define EV_CLOSURE_EVENT_FINALIZE_FREE 6
/** @} */