通过core模块ngx_events_module支持的events指令加载event二级模块;
执行events指令时,调用回调函数ngx_events_block;
该函数负责创建ngx_events_module的context,并将其保存在cycle->conf_ctx[ngx_events_module.index]处;
其类型类似 struct { void **conf_ctx; }; 示意图如下:
为event二级模块(即类型为NGX_EVENT_MODULE的模块)分配ctx_index,计算ngx_event_max_module;
创建context,为event二级模块创建大小为ngx_event_max_module的void *类型数组,用来保存它们的context;
为event二级模块调用create_conf回调函数创建context,并保存在相应槽位(下标为ngx_module_t::ctx_index);
保存当前ngx_conf_t现场;
修改conf->ctx,设置conf->module_type为NGX_EVNET_MODULE,设置conf->cmd_type为NGX_EVENT_CONF;
调用ngx_conf_parse(conf, NULL)解析加载events块的配置指令;
恢复当前ngx_conf_t现场;
为event二级模块调用init_conf回调函数;
ngx_event_core_module是event的核心模块:
worker_connections和connections(废弃)带一个int类型参数指定cycle::connexction_n,默认值为512;
use指令指出使用的event模型(epoll or select等);
mutil_accept默认为0,accept_mutex默认为1,accept_mutex_delay默认为500;
ngx_event_core_init_conf函数为参数ngx_event_conf_t赋默认值,其中最重要的是,配置文件未使用use指令明确指出使用的event模型时,该函数会按照kqueue、devpoll、epoll、rtsig、select、event_core(NULLs)顺序选择event模型;
ngx_epoll_module仅有两条指令epoll_events和worker_aio_requests分别设置ngx_epoll_conf_t::events和ngx_epoll_conf_t::aio_requests;
最后两个重要的函数调用为ngx_event_module_init和ngx_event_process_init;
ngx_event_module_init函数
该函数主进程调用一次;
初始化ngx_timer_resolution;
master调用该函数时,会创建一段共享内存;
初始化ngx_accept_mutex共享锁;
共享内存内还保存着一些统计信息(ngx_accept_mutex,ngx_connection_counter,ngx_temp_number,ngx_stat_accepted,ngx_stat_handled,ngx_stat_requests,ngx_stat_active,ngx_stat_reading,ngx_stat_writing,ngx_stat_waiting);
ngx_event_process_init函数
该函数在子进程启动时调用一次;
配置文件中指定了master、accept_mutex且worker_processors大于1时,才设置ngx_use_accept_mutex;
创建ngx_posted_events_mutex;
调用ngx_event_timer_init初始化定时器,创建ngx_event_timer_mutex;
根据ngx_event_conf_t::use找出所使用的event模块,调用其actions.init(cycle, ngx_timer_resolution)回调函数;
初始化定时器,使用ITIMER_REAL类型timer,每个ngx_timer_resolution毫秒调用一次信号回调函数ngx_timer_signal_handler;
初始化cycle->connections,cycle->read_events和cycle->write_events,这些数组大小为cycle->connection_n;
将cycle->connections串联成链表,赋值cycle->free_connections和cycle->free_connection_n;
遍历cycle->listening数组,为其分配connection,设置rev->handler = ngx_event_accept,如果ngx_use_accept_mutex没有设置时,通过调用ngx_add_event(rev, NGX_READ_EVENT, 0)将listening fd加入到event模型中;
当listening socket可读时,调用ngx_event_accept函数accept新connection;
使用epoll模型时,调用actions.init(cycle, ngx_timer_resolution)其实是调用ngx_epoll_init函数
ngx_io是nginx抽象出的io回调函数集合:该函数创建epoll,初始化event_list;
设置ngx_io = ngx_os_io;
设置ngx_event_actions = ngx_epoll_module_ctx.actions;
设置ngx_event_flags = NGX_USE_CLEAR_EVENT | NGX_USE_GREEDY_EVENT | NGX_USE_EPOLL_EVENT;
25 typedef struct {
26 ngx_recv_pt recv;
27 ngx_recv_chain_pt recv_chain;
28 ngx_recv_pt udp_recv;
29 ngx_send_pt send;
30 ngx_send_chain_pt send_chain;
31 ngx_uint_t flags;
32 } ngx_os_io_t;
ngx_event_actions是nginx抽象出来的event模型回调函数集合:
220 typedef struct {
221 ngx_int_t (*add)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);
222 ngx_int_t (*del)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);
223
224 ngx_int_t (*enable)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);
225 ngx_int_t (*disable)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);
226
227 ngx_int_t (*add_conn)(ngx_connection_t *c);
228 ngx_int_t (*del_conn)(ngx_connection_t *c, ngx_uint_t flags);
229
230 ngx_int_t (*process_changes)(ngx_cycle_t *cycle, ngx_uint_t nowait);
231 ngx_int_t (*process_events)(ngx_cycle_t *cycle, ngx_msec_t timer,
232 ngx_uint_t flags);
233
234 ngx_int_t (*init)(ngx_cycle_t *cycle, ngx_msec_t timer);
235 void (*done)(ngx_cycle_t *cycle);
236 } ngx_event_actions_t;