libevent 头文件分析
libevent 头文件分析
libevent提供的头文件都在
event2目录下,主要分成三类:
- API头文件:定义libevent的公共接口
- 兼容头文件:为已废弃的函数提供兼容的头文件,不应该使用这类头文件,它们的存在是为了兼容老版本的libevent
- 结构头文件:这类头文件定义了各种结构体,但是不是以一种稳定的方式提供。它们中有些是因为历史原因,有些是为了提供快速访问。如果直接依赖了这些头文件,可能会破坏程序对其他版本libevent的二进制兼容性,这类文件通常以struct.h结尾。
libevent核心头文件
event2/event.hlibevent最主要的头文件,提供了对事件以及事件循环的支持。是libevent库最主要的头文件event2/thread.h导出了一些方便让多线程程序使用libevent库的函数。event2/buffer.h为了方便收发网络数据,定义了自己的buffer结构和相关的操作函数。提供网络读写的buffer管理event2/bufferevent.h在buffer数据结构基础上的添加了对event的封装。提供网络读写的buffer管理event2/util.h
定义了一些方便跨平台使用和函数和一些socket相关的操作函数。比如:- 定义了一些基本数据类型——
ev_uint64_t,ev_int64_t,ev_ssize_t等等类似的标准int类型 - 定义了一些socket相关类型——
ev_socklen_t,evutil_socket_t - 声明了一些socket操作——
evutil_socketpai,evutil_make_socket_nonblocking等等,这些操作函数开头都有EVENT2_EXPORT_SYMBOL宏修饰
- 定义了一些基本数据类型——
定义这些东西其实都是为了实现跨平台兼容。
头文件简单解读
event2/event.h
Core functions for waiting for and receiving events, and using event bases.
该文件提供用来接受事件使用事件的核心函数,每一个使用libevent库的程序都必须include它。
event2/event_struct.h
Structures used by event.h. Using these structures directly WILL harm forward compatibility: be careful.
该头文件提供了一些在event.h中使用到的结构体:event_callback, event, event_list, event_dlist。如果我们直接在自己的代码中使用这些结构体,有可能会影响程序的向前兼容性,也就是说如果libevent版本更新了,这些结构体可能会发生变化,此时你的程序就会在新版本上产生兼容性问题。
event2/event_compact.h
Potentially non-threadsafe versions of the functions in event.h: provided only for backwards compatibility.
该文件提供了一些已经被废弃的函数,目的是为了兼容老版本的libevent,在新写的程序中尽量不要使用他们。
event2/thread.h
除开注释,这部分文件还是挺短的:
#ifndef EVENT2_THREAD_H_INCLUDED_
#define EVENT2_THREAD_H_INCLUDED_
#include <event2/visibility.h>
#ifdef __cplusplus
extern "C" {
#endif
#include <event2/event-config.h>
#define EVTHREAD_WRITE 0x04
#define EVTHREAD_READ 0x08
#define EVTHREAD_TRY 0x10
/**@}*/
#if !defined(EVENT__DISABLE_THREAD_SUPPORT) || defined(EVENT_IN_DOXYGEN_)
#define EVTHREAD_LOCK_API_VERSION 1
#define EVTHREAD_LOCKTYPE_RECURSIVE 1
#define EVTHREAD_LOCKTYPE_READWRITE 2
struct evthread_lock_callbacks {
int lock_api_version;
unsigned supported_locktypes;
void *(*alloc)(unsigned locktype);
void (*free)(void *lock, unsigned locktype);
int (*lock)(unsigned mode, void *lock);
int (*unlock)(unsigned mode, void *lock);
};
EVENT2_EXPORT_SYMBOL
int evthread_set_lock_callbacks(const struct evthread_lock_callbacks *);
#define EVTHREAD_CONDITION_API_VERSION 1
struct timeval;
struct evthread_condition_callbacks {
int condition_api_version;
void *(*alloc_condition)(unsigned condtype);
void (*free_condition)(void *cond);
int (*signal_condition)(void *cond, int broadcast);
int (*wait_condition)(void *cond, void *lock,
const struct timeval *timeout);
};
EVENT2_EXPORT_SYMBOL
int evthread_set_condition_callbacks(
const struct evthread_condition_callbacks *);
EVENT2_EXPORT_SYMBOL
void evthread_set_id_callback(
unsigned long (*id_fn)(void));
#if (defined(_WIN32) && !defined(EVENT__DISABLE_THREAD_SUPPORT)) || defined(EVENT_IN_DOXYGEN_)
EVENT2_EXPORT_SYMBOL
int evthread_use_windows_threads(void);
#define EVTHREAD_USE_WINDOWS_THREADS_IMPLEMENTED 1
#endif
#if defined(EVENT__HAVE_PTHREADS) || defined(EVENT_IN_DOXYGEN_)
EVENT2_EXPORT_SYMBOL
int evthread_use_pthreads(void);
#define EVTHREAD_USE_PTHREADS_IMPLEMENTED 1
#endif
EVENT2_EXPORT_SYMBOL
void evthread_enable_lock_debugging(void);
#endif /* EVENT__DISABLE_THREAD_SUPPORT */
struct event_base;
EVENT2_EXPORT_SYMBOL
int evthread_make_base_notifiable(struct event_base *base);
#ifdef __cplusplus
}
#endif
#endif /* EVENT2_THREAD_H_INCLUDED_ */
该头文件提供的内容主要是为了libevent定制多线程服务的,具体的解读在之后单独开一章。
event2/buffer.h
Functions for buffering data for network sending or receiving.
提供用于在网络收发时缓存数据的功能
event2/buffer_compat.h
Obsolete and deprecated versions of the functions in buffer.h: provided only for backward compatibility.
一些不建议使用和完全废弃的函数,只是为了提供向后兼容性。
event2/bufferevent.h
提供比evbuffer更高层次的功能:每一个bufferevent用于读写的evbuffer并且在特定情况下可以触发回调函数。
event2/bufferevent_compat.h
没啥好看的,提供了两个函数(还有一个是废弃的),不过可以看看那个被废弃函数的注释。
event2/bufferevent_ssl.h
OpenSSL support for bufferevents.
为libevent提供openssl支持,也没什么好看的,具体看如何应用。
event2/bufferevent_struct.h
Data structures for bufferevents. Using these structures may hurt forward compatibility with later versions of Libevent: be careful!
和event2/event_struct.h一样,直接使用有可能会影响程序的向前兼容性。
event2/util.h
这个也不多说了,工具函数之类,有空再说。
其他头文件
event2/visibility.h定义了用于导出库符号的宏EVENT2_EXPORT_SYMBOLevent2/tag.h导出了一些方便读写buffer中tagged数据的函数。event2/tag_compat.h定义了几个因为不规范被废弃的函数,为了兼容旧版本,对这些函数以宏的方式包装,本体都在tag.h中。event2/rpc.h提供对RPC服务器和客户端的支持,可以利用libevent实现一个基本的RPC服务。一个支持创建RPC服务器和客户端的frameworkevent2/rpc_struct.h提供rpc相关的数据结构。event2/rpc_compat.h定义了几个被废弃的函数,为了兼容旧版本,对这些函数以宏的方式包装,本体都在rpc.h中。event2/listener.h导出了一些连接监听的函数。event2/keyvalq_struct.h定义了一个tailqueen数据结构和键值对数据结构。event2/http.h导出了一些方便实现http服务的函数。内嵌的基于libevent的http服务event2/http_struct.h定义了为http服务的一些数据结构。event2/http_compat.h导出了几个http.h中因为不规范被废弃的函数,为了兼容旧版本。event2/dns.h导出了一些dns操作相关的函数。异步DNS解析event2/dns_struct.h定义了为dns服务的数据结构。event2/dns_compat.h导出了几个dns.h中可能非线程安全的函数,为了兼容旧版本。
根据以上的初步了解,决定先从event2/event.h, event2/thread.h, event2/buffer.h, event2/bufferevent.h, event2/util.h这五个核心文件入手学习libevent。
通过头文件的分析,我们大致可以看出libevent 由下列组件构成:
-
evutil:用于抽象不同平台网络实现差异的通用功能。
-
event 和 event_base:libevent 的核心,为各种平台特定的、基于事件的非阻塞 IO 后端提供抽象 API,让程序可以知道套接字何时已经准备好,可以读或者写,并且处理基本的超时功能,检测 OS 信号。
-
bufferevent:为 libevent 基于事件的核心提供使用更方便的封装。除了通知程序套接字已经准备好读写之外,还让程序可以请求缓冲的读写操作,可以知道何时 IO 已经真正发生。 (bufferevent 接口有多个后端,可以采用系统能够提供的更快的非阻塞 IO 方式,如 Windows 中的 IOCP。)
-
evbuffer:在 bufferevent 层之下实现了缓冲功能,并且提供了方便有效的访问函数。
-
evhttp:一个简单的 HTTP 客户端/服务器实现。
-
evdns:一个简单的 DNS 客户端/服务器实现。
-
evrpc:一个简单的 RPC 实现。

浙公网安备 33010602011771号