nginx的一切都是通过ngx_cycle_s来展开的,按看一下其第一个参数:
struct ngx_cycle_s {
void ****conf_ctx;
ngx_pool_t *pool;
...
}
注意conf_ctx有四个指针,就是数组的数组,那么它是怎么初始化的呢?
我们在这里先列出几个核心模块:
//第一个核心模块为ngx_core_module,在nginx.c中
static ngx_command_t ngx_core_commands[] = {
{ ngx_string("daemon"),
NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_FLAG,
ngx_conf_set_flag_slot,
0,
offsetof(ngx_core_conf_t, daemon),
NULL },
{ ngx_string("master_process"),
NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_FLAG,
ngx_conf_set_flag_slot,
0,
offsetof(ngx_core_conf_t, master),
NULL },
....
}
static ngx_core_module_t ngx_core_module_ctx = {
ngx_string("core"),
ngx_core_module_create_conf,
ngx_core_module_init_conf
};
ngx_module_t ngx_core_module = {
NGX_MODULE_V1,
&ngx_core_module_ctx, /* module context */
ngx_core_commands, /* module directives */
NGX_CORE_MODULE, /* module type */
NULL, /* init master */
NULL, /* init module */
NULL, /* init process */
NULL, /* init thread */
NULL, /* exit thread */
NULL, /* exit process */
NULL, /* exit master */
NGX_MODULE_V1_PADDING
};
//第二个模块是conf模块,只有一个,比较特殊
static ngx_command_t ngx_conf_commands[] = {
{ ngx_string("include"),
NGX_ANY_CONF|NGX_CONF_TAKE1,
ngx_conf_include,
0,
0,
NULL },
ngx_null_command
};
ngx_module_t ngx_conf_module = {
NGX_MODULE_V1,
NULL, /* module context */
ngx_conf_commands, /* module directives */
NGX_CONF_MODULE, /* module type */
NULL, /* init master */
NULL, /* init module */
NULL, /* init process */
NULL, /* init thread */
NULL, /* exit thread */
ngx_conf_flush_files, /* exit process */
NULL, /* exit master */
NGX_MODULE_V1_PADDING
};
/* The eight fixed arguments */
static ngx_uint_t argument_number[] = {
NGX_CONF_NOARGS,
NGX_CONF_TAKE1,
NGX_CONF_TAKE2,
NGX_CONF_TAKE3,
NGX_CONF_TAKE4,
NGX_CONF_TAKE5,
NGX_CONF_TAKE6,
NGX_CONF_TAKE7
};
//第三个核心模块为ngx_events_module,在ngx_event.c中
static ngx_command_t ngx_events_commands[] = {
{ ngx_string("events"),
NGX_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
ngx_events_block,
0,
0,
NULL },
ngx_null_command
};
static ngx_core_module_t ngx_events_module_ctx = {
ngx_string("events"),
NULL,
ngx_event_init_conf
};
ngx_module_t ngx_events_module = {
NGX_MODULE_V1,
&ngx_events_module_ctx, /* module context */
ngx_events_commands, /* module directives */
NGX_CORE_MODULE, /* module type */
NULL, /* init master */
NULL, /* init module */
NULL, /* init process */
NULL, /* init thread */
NULL, /* exit thread */
NULL, /* exit process */
NULL, /* exit master */
NGX_MODULE_V1_PADDING
};
//第四个核心模块是ngx_http_module,在ngx_http.c中
ngx_uint_t ngx_http_max_module;
ngx_http_output_header_filter_pt ngx_http_top_header_filter;
ngx_http_output_body_filter_pt ngx_http_top_body_filter;
ngx_http_request_body_filter_pt ngx_http_top_request_body_filter;
static ngx_command_t ngx_http_commands[] = {
{ ngx_string("http"),
NGX_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
ngx_http_block,
0,
0,
NULL },
ngx_null_command
};
static ngx_core_module_t ngx_http_module_ctx = {
ngx_string("http"),
NULL,
NULL
};
ngx_module_t ngx_http_module = {
NGX_MODULE_V1,
&ngx_http_module_ctx, /* module context */
ngx_http_commands, /* module directives */
NGX_CORE_MODULE, /* module type */
NULL, /* init master */
NULL, /* init module */
NULL, /* init process */
NULL, /* init thread */
NULL, /* exit thread */
NULL, /* exit process */
NULL, /* exit master */
NGX_MODULE_V1_PADDING
};
//第五个核心模块是ngx_rtmp_module
ngx_uint_t ngx_rtmp_max_module;
static ngx_command_t ngx_rtmp_commands[] = {
{ ngx_string("rtmp"),
NGX_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
ngx_rtmp_block,
0,
0,
NULL },
ngx_null_command
};
static ngx_core_module_t ngx_rtmp_module_ctx = {
ngx_string("rtmp"),
NULL,
NULL
};
ngx_module_t ngx_rtmp_module = {
NGX_MODULE_V1,
&ngx_rtmp_module_ctx, /* module context */
ngx_rtmp_commands, /* module directives */
NGX_CORE_MODULE, /* module type */
NULL, /* init master */
NULL, /* init module */
ngx_rtmp_init_process, /* init process */
NULL, /* init thread */
NULL, /* exit thread */
NULL, /* exit process */
NULL, /* exit master */
NGX_MODULE_V1_PADDING
};
以上就是我们本次关心的几个核心模块
下面再ngx_cycle.c的main中:
main-->ngx_init_cycle(){
...
//在这里分配空间,ngx_max_module就是ngx_module_t *ngx_modules[] + 128,
//ngx_modules[]有config生成:
//ngx_module_t *ngx_modules[] = {
// &ngx_core_module,
// &ngx_errlog_module,
// &ngx_conf_module,
// &ngx_rtmp_module,
// &ngx_rtmp_core_module,
// ‘’‘’
// &ngx_openssl_module,
// &ngx_regex_module, //通配符
// &ngx_events_module,
// &ngx_event_core_module,
// &ngx_epoll_module,
// &ngx_http_module,
// &ngx_http_core_module,
// ‘’‘’‘
//
// }
cycle->conf_ctx = ngx_pcalloc(pool, ngx_max_module * sizeof(void *));
if (cycle->conf_ctx == NULL) {
ngx_destroy_pool(pool);
return NULL;
}
...
//在这里调用核心模块的create_conf函数,通过上面可以知道,只有ngx_core_module才有create_conf
//其余核心模块没有,那么其余模块是在什么时候create_conf呢?
//其实其余的都是在 ngx_xxxx_block,中开始创建的
for (i = 0; cycle->modules[i]; i++) {
if (cycle->modules[i]->type != NGX_CORE_MODULE) {
continue;
}
module = cycle->modules[i]->ctx;
if (module->create_conf) {
rv = module->create_conf(cycle);
if (rv == NULL) {
ngx_destroy_pool(pool);
return NULL;
}
cycle->conf_ctx[cycle->modules[i]->index] = rv;
}
}
’‘’‘’‘
//在这个for循环中进行NGX_CORE_MODULE初始化
for (i = 0; cycle->modules[i]; i++) {
if (cycle->modules[i]->type != NGX_CORE_MODULE) {
continue;
}
module = cycle->modules[i]->ctx;
if (module->init_conf) {
if (module->init_conf(cycle,
cycle->conf_ctx[cycle->modules[i]->index])
== NGX_CONF_ERROR)
{
environ = senv;
ngx_destroy_cycle_pools(&conf);
return NULL;
}
}
}
’‘’‘
//注意这个conf是做什么用的?
//struct ngx_conf_s {
// char *name;
// ngx_array_t *args;
//
// ngx_cycle_t *cycle;
// ngx_pool_t *pool;
// ngx_pool_t *temp_pool;
// ngx_conf_file_t *conf_file;
// ngx_log_t *log;
//
// void *ctx;
// ngx_uint_t module_type;
// ngx_uint_t cmd_type;
// ngx_conf_handler_pt handler;
// void *handler_conf;
//};
ngx_memzero(&conf, sizeof(ngx_conf_t));
/* STUB: init array ? */
conf.args = ngx_array_create(pool, 10, sizeof(ngx_str_t));
if (conf.args == NULL) {
ngx_destroy_pool(pool);
return NULL;
}
conf.temp_pool = ngx_create_pool(NGX_CYCLE_POOL_SIZE, log);
if (conf.temp_pool == NULL) {
ngx_destroy_pool(pool);
return NULL;
}
conf.ctx = cycle->conf_ctx;
conf.cycle = cycle;
conf.pool = pool;
conf.log = log;
conf.module_type = NGX_CORE_MODULE;
conf.cmd_type = NGX_MAIN_CONF;
if (ngx_conf_param(&conf) != NGX_CONF_OK) {
environ = senv;
ngx_destroy_cycle_pools(&conf);
return NULL;
}
//这里就是开始解析配置文件了,注意传入的conf
//ngx_conf_parse---->
// for(;;){
// rc = ngx_conf_read_token(cf);
// //核心就在这里
// rc = ngx_conf_handler(cf, rc);
//}
//ngx_conf_handler核心for循环{}如下:
//遍历所有commands
// name = cf->args->elts;这个name就是解析到的nginx.conf
//关于nginx.conf可以参考:
//for (i = 0; cf->cycle->modules[i]; i++) {
// cmd = cf->cycle->modules[i]->commands;
// if (cmd == NULL) {
// continue;
// }
// for ( /* void */ ; cmd->name.len; cmd++) {//简单len比较
// if (name->len != cmd->name.len) {
// continue;
// }
// if (ngx_strcmp(name->data, cmd->name.data) != 0) {//len相等再对str比较
// continue;
// }
// found = 1;//说明字符串跟command中的相同
// //如果模块类型不符返回
// if (cf->cycle->modules[i]->type != NGX_CONF_MODULE
// && cf->cycle->modules[i]->type != cf->module_type)
// {
// continue;
// }
‘‘’
// cmd就是执行核心模块的command中的set,因为在配置文件中只有核心模块的名字
// http 、rtmp 、events 才出现在配置文件中,更加确切的说,这里执行的是核心模块
// 的 ngx_xxxx_block,继续创建NGX_EVENT_MODULE、
//struct ngx_command_s {
// ngx_str_t name;
// ngx_uint_t type;
// char *(*set)(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
// ngx_uint_t conf;
// ngx_uint_t offset;
// void *post;
};
// rv = cmd->set(cf, cmd, conf);//关键在这里
// if (rv == NGX_CONF_OK) {
// return NGX_OK;
// }
// if (rv == NGX_CONF_ERROR) {
// return NGX_ERROR;
// }
// ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"\"%s\" directive %s", name->data, rv);
// return NGX_ERROR;
// }
// }
if (ngx_conf_parse(&conf, &cycle->conf_file) != NGX_CONF_OK) {
environ = senv;
ngx_destroy_cycle_pools(&conf);
return NULL;
}
}