struct ngx_cycle_s {
void ****conf_ctx; //一些配置上下文
ngx_pool_t *pool; //内存池
ngx_log_t *log; //日志
ngx_log_t new_log;
ngx_connection_t **files; //所有在线的connection
ngx_connection_t *free_connections; //当前空闲可用的connection
ngx_uint_t free_connection_n; //空闲connection的数量
ngx_queue_t reusable_connections_queue;
ngx_array_t listening; //保存所有的监听套接字
ngx_array_t pathes;
ngx_list_t open_files; //保存所有打开的文件
ngx_list_t shared_memory;
ngx_uint_t connection_n; //连接的个数
ngx_uint_t files_n; //打开文件的个数
ngx_connection_t *connections;
ngx_event_t *read_events; //读事件
ngx_event_t *write_events; //写事件
ngx_cycle_t *old_cycle;
ngx_str_t conf_file; //配置文件
ngx_str_t conf_param; //配置参数
ngx_str_t conf_prefix; //配置前缀
ngx_str_t prefix; //前缀
ngx_str_t lock_file; //锁文件
ngx_str_t hostname; //主机名字
};
至于每一个域的作用在上面已经说清楚了,然后接下来可以看初始这个全局变量的函数了ngx_init_cycle(),该函数的定义在Ngx_cycle.c当中。
这里我们分段来解析这个函数:
(1)调用ngx_timezone_update以及ngx_time_update函数更新时间相关的一些东西。
ngx_timezone_update();
tp = ngx_timeofday();
tp->sec = 0;
ngx_time_update();(2)创建内存池,并为新的cycle变量分配内存,以及初始化
//创建内存池
pool = ngx_create_pool(NGX_CYCLE_POOL_SIZE, log);
if (pool == NULL) {
return NULL;
}
pool->log = log;
//在内存池中分配cycle的内存空间
cycle = ngx_pcalloc(pool, sizeof(ngx_cycle_t));
if (cycle == NULL) {
ngx_destroy_pool(pool);
return NULL;
}
//初始化cycle的一些数据
cycle->pool = pool;
cycle->log = log;
cycle->new_log.log_level = NGX_LOG_ERR;
cycle->old_cycle = old_cycle;(3)初始化配置前缀,前缀,配置文件,配置参数等字符串
cycle->conf_prefix.len = old_cycle->conf_prefix.len;
cycle->conf_prefix.data = ngx_pstrdup(pool, &old_cycle->conf_prefix);
if (cycle->conf_prefix.data == NULL) {
ngx_destroy_pool(pool);
return NULL;
}
cycle->prefix.len = old_cycle->prefix.len;
cycle->prefix.data = ngx_pstrdup(pool, &old_cycle->prefix);
if (cycle->prefix.data == NULL) {
ngx_destroy_pool(pool);
return NULL;
}
cycle->conf_file.len = old_cycle->conf_file.len;
cycle->conf_file.data = ngx_pnalloc(pool, old_cycle->conf_file.len + 1);
if (cycle->conf_file.data == NULL) {
ngx_destroy_pool(pool);
return NULL;
}
ngx_cpystrn(cycle->conf_file.data, old_cycle->conf_file.data,
old_cycle->conf_file.len + 1);
cycle->conf_param.len = old_cycle->conf_param.len;
cycle->conf_param.data = ngx_pstrdup(pool, &old_cycle->conf_param);
if (cycle->conf_param.data == NULL) {
ngx_destroy_pool(pool);
return NULL;
}(4)初始化pathes数组的信息:
n = old_cycle->pathes.nelts ? old_cycle->pathes.nelts : 10;
cycle->pathes.elts = ngx_pcalloc(pool, n * sizeof(ngx_path_t *));
if (cycle->pathes.elts == NULL) {
ngx_destroy_pool(pool);
return NULL;
}
cycle->pathes.nelts = 0;
cycle->pathes.size = sizeof(ngx_path_t *);
cycle->pathes.nalloc = n;
cycle->pathes.pool = pool;
if (old_cycle->open_files.part.nelts) {
n = old_cycle->open_files.part.nelts;
for (part = old_cycle->open_files.part.next; part; part = part->next) {
n += part->nelts;
}
} else {
n = 20;
}(5)初始化open_files链表:
if (ngx_list_init(&cycle->open_files, pool, n, sizeof(ngx_open_file_t))
!= NGX_OK)
{
ngx_destroy_pool(pool);
return NULL;
}(6)初始化共享内存:
if (old_cycle->shared_memory.part.nelts) {
n = old_cycle->shared_memory.part.nelts;
for (part = old_cycle->shared_memory.part.next; part; part = part->next)
{
n += part->nelts;
}
} else {
n = 1;
}
if (ngx_list_init(&cycle->shared_memory, pool, n, sizeof(ngx_shm_zone_t))
!= NGX_OK)
{
ngx_destroy_pool(pool);
return NULL;
}(7)初始化监听数组相关的信息:
n = old_cycle->listening.nelts ? old_cycle->listening.nelts : 10;
//分配存储监听数组的内存空间
cycle->listening.elts = ngx_pcalloc(pool, n * sizeof(ngx_listening_t));
if (cycle->listening.elts == NULL) {
ngx_destroy_pool(pool);
return NULL;
}
//设置监听数组的一些基本信息
cycle->listening.nelts = 0;
cycle->listening.size = sizeof(ngx_listening_t);
cycle->listening.nalloc = n;
cycle->listening.pool = pool;
(8)初始化reusable_connections_queue
ngx_queue_init(&cycle->reusable_connections_queue);(9)为配置上下文分指针配内存
//为配置上下文分配内存
cycle->conf_ctx = ngx_pcalloc(pool, ngx_max_module * sizeof(void *)); //说白了就是一个指针数组
if (cycle->conf_ctx == NULL) {
ngx_destroy_pool(pool);
return NULL;
}
(10)初始化hostname
(11)循环遍历全局变量ngx_modules,找到所有的core module,并调用它们的create_conf函数为它们创建配置,并将最终配置的信息保存到cycle的conf_ctx相应的位置当中去。其实这里比较有意思的地方时,所有core类型的模块有ngx_core_module,ngx_errlog_module,ngx_events_module,ngx_http_module,但是只有ngx_core_module模块注册了相应的create_conf函数,其余的都为NULL,因此这里其实也就只调用了ngx_core_module的create_conf函数,为该模块创建了配置,其余的core类型的模块并没有创建
for (i = 0; ngx_modules[i]; i++) {
if (ngx_modules[i]->type != NGX_CORE_MODULE) {
continue;
}
module = ngx_modules[i]->ctx;
if (module->create_conf) { //创建模块的配置
rv = module->create_conf(cycle);
if (rv == NULL) {
ngx_destroy_pool(pool);
return NULL;
}
cycle->conf_ctx[ngx_modules[i]->index] = rv; //在cycle的conf_ctx的相应位置保存创建的配置
}
}
(12)配置文件的解析,这里通过解析配置文件会调用相应命令的set回调函数,也是很重要的一个过程:
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 0
log->log_level = NGX_LOG_DEBUG_ALL;
#endif
//一些配置文件的解析
if (ngx_conf_param(&conf) != NGX_CONF_OK) {
environ = senv;
ngx_destroy_cycle_pools(&conf);
return NULL;
}
if (ngx_conf_parse(&conf, &cycle->conf_file) != NGX_CONF_OK) {
environ = senv;
ngx_destroy_cycle_pools(&conf);
return NULL;
}(13)调用所有core模块的init_conf()函数
for (i = 0; ngx_modules[i]; i++) {
if (ngx_modules[i]->type != NGX_CORE_MODULE) {
continue;
}
module = ngx_modules[i]->ctx;
if (module->init_conf) {
if (module->init_conf(cycle, cycle->conf_ctx[ngx_modules[i]->index])
== NGX_CONF_ERROR)
{
environ = senv;
ngx_destroy_cycle_pools(&conf);
return NULL;
}
}
}
(14)遍历open_files链表,并将它们打开
(15)创建共享内存,并初始化它们
(16)遍历listen数组,打开所有的socket
(17)调用所有模块的init_module,其实只有ngx_event_core_module一个模块定义了这个回调函数
for (i = 0; ngx_modules[i]; i++) {
if (ngx_modules[i]->init_module) {
if (ngx_modules[i]->init_module(cycle) != NGX_OK) {
/* fatal */
exit(1);
}
}
}(18)关闭一些残留的资源,并返回cycle
本文详细介绍了nginx中的核心变量ngx_cycle,包括其结构体定义、各字段含义及ngx_init_cycle函数的实现过程。从内存池创建到配置文件解析,再到监听套接字与共享内存的初始化。
966

被折叠的 条评论
为什么被折叠?



