不同的操作系统对应不同的事件驱动机制,在Linux 2.6之后使用epoll机制,对应的事件驱动模块是ngx_epoll_module。Nginx的ngx_event_core_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);
// 每个事件模块需要实现的10个抽象方法
ngx_event_actions_t actions;
} ngx_event_module_t; // 事件模块通用接口// 每个事件模块需要实现的10个方法
typedef struct
{
// 将一个事件添加到事件驱动机制
ngx_int_t (*add)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);
// 将一个事件从事件驱动机制中删除
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);
// 将一个连接添加到事件驱动机制中,连接上的读、写事件即被加入到了事件驱动机制中
ngx_int_t (*add_conn)(ngx_connection_t *c);
// 从事件驱动机制中删除一个连接的读、写事件
ngx_int_t (*del_conn)(ngx_connection_t *c, ngx_uint_t flags);
// 暂无用
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_int_t (*init)(ngx_cycle_t *cycle, ngx_msec_t timer);
// 事件驱动模块退出前调用的方法
void (*done)(ngx_cycle_t *cycle);
} ngx_event_actions_t;typedef struct ngx_event_s ngx_event_t; // 代表事件的结构体
// 代表事件的结构体
struct ngx_event_s {
...
ngx_event_handler_pt handler; // 核心,事件消费函数,定义如何处理事件
...
}; struct ngx_cycle_s {
...
ngx_connection_t *connections; // 保存当前进程中所有的连接
ngx_event_t *read_events; // 保存所有的读事件
ngx_event_t *write_events; // 保存所有的写事件
...
}; // 表示一个连接的结构体
struct ngx_connection_s {
void *data; // 连接未使用时,充当next指针连接池中下一个空闲的连接,当被使用时,是具体情况而定
ngx_event_t *read; // 连接对应的读事件
ngx_event_t *write; // 连接对应的写事件
ngx_socket_t fd; // 套接字描述符
ngx_recv_pt recv; // 接收方法1
ngx_send_pt send; // 发送方法1
ngx_recv_chain_pt recv_chain; // 接收方法2
ngx_send_chain_pt send_chain; // 发送方法2
ngx_listening_t *listening; // 连接对应的监听对象
off_t sent; // 已发出去的字节数
ngx_log_t *log;
ngx_pool_t *pool; // 内存池
struct sockaddr *sockaddr; // 保存网络地址
socklen_t socklen; // 网络地址长度
ngx_str_t addr_text; // 客户端IP地址
ngx_str_t proxy_protocol_addr;
struct sockaddr *local_sockaddr; // 本机所监听的网络地址
socklen_t local_socklen; // 网络地址长度
ngx_buf_t *buffer; // 接收buffer
...
}; 原文:http://blog.csdn.net/nestler/article/details/37570401