ngx_init_cycle函数创建并初始化ngx_cycle_t结构, 并且初始化nginx的模块.
下面以第一次启动nginx并且是以master方式运行. 来看ngx_init_cycle函数所做的事情.
点击(此处)折叠或打开
- ngx_timezone_update();
-
ngx_time_update();
更新时区之后, 调用ngx_time_update来更新缓存的时间. 为了减少调用获取时间的函数的次数, nginx在一定的时间精度内将时间缓存起来. 获取时间只需要一次内存访问即可.
点击(此处)折叠或打开
-
pool = ngx_create_pool(NGX_CYCLE_POOL_SIZE, log);
- cycle = ngx_pcalloc(pool, sizeof(ngx_cycle_t));
接下来所做的事情就是将old_cycle中的prefix, conf_prefix, conf_file这几个字段拷贝过来. 注意是深拷贝,
这些字段是在ngx_process_options函数中初始化的. 代码就不贴出来了.
点击(此处)折叠或打开
-
n = old_cycle->paths.nelts ? old_cycle->paths.nelts : 10;
-
-
cycle->paths.elts = ngx_pcalloc(pool, n * sizeof(ngx_path_t *));
-
if (cycle->paths.elts == NULL) {
-
ngx_destroy_pool(pool);
-
return NULL;
-
}
-
-
cycle->paths.nelts = 0;
-
cycle->paths.size = sizeof(ngx_path_t *);
-
cycle->paths.nalloc = n;
- cycle->paths.pool = pool;
关于nginx的动态数组见http://blog.chinaunix.net/uid-22577711-id-4389317.html
点击(此处)折叠或打开
-
if (ngx_list_init(&cycle->open_files, pool, n, sizeof(ngx_open_file_t))
- != NGX_OK)
点击(此处)折叠或打开
-
if (ngx_list_init(&cycle->shared_memory, pool, n, sizeof(ngx_shm_zone_t))
- != NGX_OK)
点击(此处)折叠或打开
-
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;
点击(此处)折叠或打开
- ngx_queue_init(&cycle->reusable_connections_queue);
点击(此处)折叠或打开
- cycle->conf_ctx = ngx_pcalloc(pool, ngx_max_module * sizeof(void *));
点击(此处)折叠或打开
-
if (gethostname(hostname, NGX_MAXHOSTNAMELEN) == -1) {
-
ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "gethostname() failed");
-
ngx_destroy_pool(pool);
-
return NULL;
-
}
-
-
/* on Linux gethostname() silently truncates name that does not fit */
-
-
hostname[NGX_MAXHOSTNAMELEN - 1] = '\0';
-
cycle->hostname.len = ngx_strlen(hostname);
-
-
cycle->hostname.data = ngx_pnalloc(pool, cycle->hostname.len);
-
if (cycle->hostname.data == NULL) {
-
ngx_destroy_pool(pool);
-
return NULL;
-
}
-
- ngx_strlow(cycle->hostname.data, (u_char *) hostname, cycle->hostname.len);
接下来的代码就是关于模块配置上下文的创建, 配置文件的解析, 配置上下文的初始化.
过程见http://blog.chinaunix.net/uid-22577711-id-4410347.html
点击(此处)折叠或打开
-
if (ngx_create_paths(cycle, ccf->user) != NGX_OK) {
-
goto failed;
- }
点击(此处)折叠或打开
-
if (ngx_log_open_default(cycle) != NGX_OK) {
-
goto failed;
- }
点击(此处)折叠或打开
-
part = &cycle->open_files.part;
-
file = part->elts;
-
-
for (i = 0; /* void */ ; i++) {
-
-
if (i >= part->nelts) {
-
if (part->next == NULL) {
-
break;
-
}
-
part = part->next;
-
file = part->elts;
-
i = 0;
-
}
-
-
if (file[i].name.len == 0) {
-
continue;
-
}
-
-
file[i].fd = ngx_open_file(file[i].name.data,
-
NGX_FILE_APPEND,
-
NGX_FILE_CREATE_OR_OPEN,
-
NGX_FILE_DEFAULT_ACCESS);
-
-
ngx_log_debug3(NGX_LOG_DEBUG_CORE, log, 0,
-
"log: %p %d \"%s\"",
-
&file[i], file[i].fd, file[i].name.data);
-
-
if (file[i].fd == NGX_INVALID_FILE) {
-
ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
-
ngx_open_file_n " \"%s\" failed",
-
file[i].name.data);
-
goto failed;
- }
- #if !(NGX_WIN32)
- if (fcntl(file[i].fd, F_SETFD, FD_CLOEXEC) == -1) {
- ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
- "fcntl(FD_CLOEXEC) \"%s\" failed",
- file[i].name.data);
- goto failed;
- }
- #endif
-
}
点击(此处)折叠或打开
-
cycle->log = &cycle->new_log;
- pool->log = &cycle->new_log;
下面跳到579行
点击(此处)折叠或打开
-
if (ngx_open_listening_sockets(cycle) != NGX_OK) {
-
goto failed;
- }
socket, bind, listen, 并且对套接字设置了地址重用选项等。
点击(此处)折叠或打开
-
if (!ngx_test_config) {
-
ngx_configure_listening_sockets(cycle);
- }
点击(此处)折叠或打开
-
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);
-
}
-
}
- }
点击(此处)折叠或打开
-
ngx_destroy_pool(conf.temp_pool);
-
if (ngx_process == NGX_PROCESS_MASTER || ngx_is_init_cycle(old_cycle)) {
-
-
/*
-
* perl_destruct() frees environ, if it is not the same as it was at
-
* perl_construct() time, therefore we save the previous cycle
-
* environment before ngx_conf_parse() where it will be changed.
-
*/
-
-
env = environ;
-
environ = senv;
-
-
ngx_destroy_pool(old_cycle->pool);
-
cycle->old_cycle = NULL;
-
-
environ = env;
-
-
return cycle;
- }
简而言之该函数所做的事情就是更新时区及时间缓存, 创建ngx_cycle_t结构并初始化一些字段, 解析配置文件, 设置好所有模块的配置上下文. 创建目录, 打开文, 监听端口.