前言
在上一小节中我们对模块的整体有了一定的把握,本小节将进入到事件模块的分析中,了解nginx是如何收集、管理、分发事件的。nginx将网络事件以及定时事件集成到一起进行管理,由于各平台的I/O多路复用机制不同,但是nginx支持多个操作系统,因此在事件模块中也实现了多种针对不同平台下封装I/O多路复用机制的模块。由于我所用的环境主要关注的是linux,因此后面主要分析ngx_epoll_module
。
事件模块具体化的通用性接口
前面说过,每一个模块都会遵循ngx_module_t
通用性接口,里面有个ctx
成员,它是一个泛型指针,可以转换为其它任何类型,因为它的存在可以让各类型模块的接口更加具体化。
对应于事件模块,则是ngx_event_module_t
:
typedef struct {
//核心模块名字
ngx_str_t *name;
//在解析配置项前,调用该方法创建用于存储配置项的数据结构
void *(*create_conf)(ngx_cycle_t *cycle);
//在解析配置项后,调用该方法用于处理当前事件模块感兴趣的配置项
char *(*init_conf)(ngx_cycle_t *cycle, void *conf);
//对于I/O多路复用机制,每个事件模块需要实现的接口
ngx_event_actions_t actions;
} ngx_event_module_t;
ngx_event_actions_t:
typedef struct {
//将事件添加到I/O多路复用机制中
ngx_int_t (*add)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);
//将事件从I/O多路复用机制的监听中移除
ngx_int_t (*del)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);
//启用事件,目前并没有使用
ngx_int_t (*enable)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);
//禁用事件,目前并没有使用
ngx_int_t (*disable)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);
//添加一个新连接到I/O多路复用机制中(这意味着该连接对应的读和写事件也已经添加到了该I/O多路复用机制中了)
ngx_int_t (*add_conn)(ngx_connection_t *c);
//从I/O多路复用机制中移除一个连接的读写事件
ngx_int_t (*del_conn)(ngx_connection_t *c, ngx_uint_t flags);
//在多线程下使用,nginx目前并没有以多线程的方式运行
ngx_int_t (*process_changes)(ngx_cycle_t *cycle, ngx_uint_t nowait);
//通过该方法来处理事件。会被ngx_process_events_and_timers调用
//它是处理以及分发事件的核心
ngx_int_t (*process_events)(ngx_cycle_t *cycle, ngx_msec_t timer,
ngx_uint_t flags);
//初始化事件驱动模块(例如ngx_epoll_module模块)
ngx_int_t (*init)(ngx_cycle_t *cycle, ngx_msec_t timer);
//退出事件模块驱动前调用的方法
void (*done)