查看源代码入门

这是一篇关于NGINX的MAIN()函数入门说明文章,相比其他这篇十分枯燥,其实写的时候更是无聊,不过学了这么长时间的WEB开发,连NGINX源代码都没有读下来,总是觉得有些缺憾,希望这一次可以弥补一下。

一、下载NGINX

  1. 下载地址:http://nginx.org/en/download.html
  2. tar -zxvf *.tar.gz && ./configure && make && sudo make install
  3. 查看NGINX目录有如下文件夹:
    • auto  CHANGES  CHANGES.ru  conf  configure  contrib  html  LICENSE  Makefile  man  objs  README  src

二、使用gdb跟踪查找入口文件

很多朋友看见NGINX目录有很多的内容,就会头疼,不知道从哪里开始,下面就分享一个方法。进入objs目录,会发现nginx是可执行文件,使用gdb跟踪一下(如果没有gdb,执行命令:sudo yum install yum安装即可),依次执行如下命令:

2.1 gdb nginx

进入nginx程序

GNU gdb (GDB) Red Hat Enterprise Linux (7.2-.el6_4.)
Copyright (C) Free Software Foundation, Inc.
License GPLv3+: GNU GPL version or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /root/soft/ngx_openresty-1.4.1.1/build/nginx-1.4./objs/nginx...done.

2.2 l main

目的是查看main函数

(gdb) l main
static char **ngx_os_environ; int ngx_cdecl
main(int argc, char *const *argv)
{
ngx_int_t i;
ngx_log_t *log;
ngx_cycle_t *cycle, init_cycle;
ngx_core_conf_t *ccf;

2.3 i li main

查看main()函数的位置

(gdb) i li main
Line of "src/core/nginx.c" starts at address 0x4168cb <main> and ends at 0x4168e1 <main+>.

如上就知道了入口程序文件是:src/core/nginx.c

三、main()函数

int ngx_cdecl
main(int argc, char *const *argv)
{
ngx_int_t i;
ngx_log_t *log;
ngx_cycle_t *cycle, init_cycle;
ngx_core_conf_t *ccf;
//上面是四个堆栈的常量,没啥别的意思。nginx的结构都是_t结束的。
ngx_debug_init();//nginx的函数都是ngx_开头的。下面有解释 if (ngx_strerror_init() != NGX_OK) {
return ;//如果启动失败
} if (ngx_get_options(argc, argv) != NGX_OK) {
return ;//检测命令行参数异常
} if (ngx_show_version) {//ngx_show_version是一个全局变量,可以在gdb里面查看(p ngx_show_version或者i var ngx_show_version)
ngx_write_stderr("nginx version: " NGINX_VER NGX_LINEFEED); if (ngx_show_help) {//自我帮助信息,执行:"nginx -?"时候输出的信息
ngx_write_stderr(
"Usage: nginx [-?hvVtq] [-s signal] [-c filename] "
"[-p prefix] [-g directives]" NGX_LINEFEED
NGX_LINEFEED
"Options:" NGX_LINEFEED
" -?,-h : this help" NGX_LINEFEED
" -v : show version and exit" NGX_LINEFEED
" -V : show version and configure options then exit"
NGX_LINEFEED
" -t : test configuration and exit" NGX_LINEFEED
" -q : suppress non-error messages "
"during configuration testing" NGX_LINEFEED
" -s signal : send signal to a master process: "
"stop, quit, reopen, reload" NGX_LINEFEED
#ifdef NGX_PREFIX
" -p prefix : set prefix path (default: "
NGX_PREFIX ")" NGX_LINEFEED
#else
" -p prefix : set prefix path (default: NONE)" NGX_LINEFEED
#endif
" -c filename : set configuration file (default: "
NGX_CONF_PATH ")" NGX_LINEFEED
" -g directives : set global directives out of configuration "
"file" NGX_LINEFEED NGX_LINEFEED
);
} if (ngx_show_configure) {
ngx_write_stderr(
#ifdef NGX_COMPILER
"built by " NGX_COMPILER NGX_LINEFEED
#endif
#if (NGX_SSL)
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
"TLS SNI support enabled" NGX_LINEFEED
#else
"TLS SNI support disabled" NGX_LINEFEED
#endif
#endif
"configure arguments:" NGX_CONFIGURE NGX_LINEFEED);
} if (!ngx_test_config) {
return ;
}
} /* TODO */ ngx_max_sockets = -; ngx_time_init();//时间初始化 #if (NGX_PCRE)
ngx_regex_init();//宏开关
#endif ngx_pid = ngx_getpid(); log = ngx_log_init(ngx_prefix);//日志初始化
if (log == NULL) {
return ;
} /* STUB */
#if (NGX_OPENSSL)
ngx_ssl_init(log);//ssh初始化
#endif /*
* init_cycle->log is required for signal handlers and
* ngx_process_options()
*/ ngx_memzero(&init_cycle, sizeof(ngx_cycle_t));//init_cycle清零
init_cycle.log = log;
ngx_cycle = &init_cycle; init_cycle.pool = ngx_create_pool(, log);//建立内存池
if (init_cycle.pool == NULL) {
return ;
} if (ngx_save_argv(&init_cycle, argc, argv) != NGX_OK) {
return ;
} if (ngx_process_options(&init_cycle) != NGX_OK) {
return ;
} if (ngx_os_init(log) != NGX_OK) {
return ;
} /*
* ngx_crc32_table_init() requires ngx_cacheline_size set in ngx_os_init()
*/ if (ngx_crc32_table_init() != NGX_OK) {
return ;//crc算法
} if (ngx_add_inherited_sockets(&init_cycle) != NGX_OK) {
return ;
} ngx_max_module = ;
for (i = ; ngx_modules[i]; i++) { //查看一共多少模块
ngx_modules[i]->index = ngx_max_module++;
} cycle = ngx_init_cycle(&init_cycle);//初始化生命周期,下面有讲
if (cycle == NULL) {
if (ngx_test_config) {
ngx_log_stderr(, "configuration file %s test failed",
init_cycle.conf_file.data);
} return ;
} if (ngx_test_config) {
if (!ngx_quiet_mode) {
ngx_log_stderr(, "configuration file %s test is successful",
cycle->conf_file.data);
} return ;
} if (ngx_signal) {
return ngx_signal_process(cycle, ngx_signal);
} ngx_os_status(cycle->log); ngx_cycle = cycle; ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); if (ccf->master && ngx_process == NGX_PROCESS_SINGLE) {
ngx_process = NGX_PROCESS_MASTER;
} #if !(NGX_WIN32) if (ngx_init_signals(cycle->log) != NGX_OK) {
return ;
} if (!ngx_inherited && ccf->daemon) {
if (ngx_daemon(cycle->log) != NGX_OK) {
return ;
} ngx_daemonized = ;
} if (ngx_inherited) {
ngx_daemonized = ;
} #endif if (ngx_create_pidfile(&ccf->pid, cycle->log) != NGX_OK) {
return ;
} if (cycle->log->file->fd != ngx_stderr) { if (ngx_set_stderr(cycle->log->file->fd) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
ngx_set_stderr_n " failed");
return ;
}
} if (log->file->fd != ngx_stderr) {
if (ngx_close_file(log->file->fd) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
ngx_close_file_n " built-in log failed");
}
} ngx_use_stderr = ; if (ngx_process == NGX_PROCESS_SINGLE) {
ngx_single_process_cycle(cycle); } else {
ngx_master_process_cycle(cycle);
} return ;
}

无疑,里面的中文内容肯定是我写的注释。

3.1 ngx_debug_init

使用gdb执行:"i li ngx_debug_init"

(gdb) i li ngx_debug_init
Function "ngx_debug_init" not defined.
(gdb)

没有找到,这个时候只能在文件里面搜索

@~/soft/ngx_openresty-1.4.1.1/build/nginx-1.4./src $ grep -r ngx_debug_init *
core/nginx.c: ngx_debug_init();
os/unix/ngx_freebsd_init.c:ngx_debug_init()
os/unix/ngx_solaris_config.h:#define ngx_debug_init()
os/unix/ngx_linux_config.h:#define ngx_debug_init()
os/unix/ngx_darwin_init.c:ngx_debug_init()
os/unix/ngx_freebsd.h:void ngx_debug_init(void);
os/unix/ngx_posix_config.h:#define ngx_debug_init()
os/unix/ngx_darwin.h:void ngx_debug_init(void);

可见这是一个操作系统相关的内容,先初始化一下。但是什么都没做,所以gdb搜索不到。

3.2 ngx_strerror_init

(gdb) i li ngx_strerror_init
Line of "src/os/unix/ngx_errno.c" starts at address 0x42d8c9 <ngx_strerror_init> and ends at 0x42d8d7 <ngx_strerror_init+>.

然后打开文件ngx_errno.c文件:

ngx_int_t
ngx_strerror_init(void)
{
char *msg;
u_char *p;
size_t len;
ngx_err_t err;
//定义四个堆栈变量
/*
* ngx_strerror() is not ready to work at this stage, therefore,
* malloc() is used and possible errors are logged using strerror().
*/ len = NGX_SYS_NERR * sizeof(ngx_str_t);
//计算长度,注意NGX_SYS_NERR不是在src里面的,而是编译的时候根据操作系统的不同而生成的不内容,这里是在objs/ngx_auto_config.h里面,定义为:135。
ngx_sys_errlist = malloc(len);//申请空间
if (ngx_sys_errlist == NULL) {
goto failed;
} for (err = ; err < NGX_SYS_NERR; err++) {
msg = strerror(err);//如果不是以ngx_开头的,都是系统函数或者其他的库函数。这里是建立一个字符串描述这个错误号
len = ngx_strlen(msg); p = malloc(len);
if (p == NULL) {
goto failed;
} ngx_memcpy(p, msg, len);//系统的错误信息拷贝到自己的空间。
ngx_sys_errlist[err].len = len;
ngx_sys_errlist[err].data = p;
} return NGX_OK; failed: err = errno;
ngx_log_stderr(, "malloc(%uz) failed (%d: %s)", len, err, strerror(err)); return NGX_ERROR;
}

作用是将全局的错误信息复制到一个数组里面,暂时不知道是为什么

3.3 ngx_init_cycle

初始化生命周期。core/ngx_cycle.c,这个函数相当的长。

ngx_cycle_t *
ngx_init_cycle(ngx_cycle_t *old_cycle)
{
void *rv;
char **senv, **env;
ngx_uint_t i, n;
ngx_log_t *log;
ngx_time_t *tp;
ngx_conf_t conf;
ngx_pool_t *pool;
ngx_cycle_t *cycle, **old;
ngx_shm_zone_t *shm_zone, *oshm_zone;
ngx_list_part_t *part, *opart;
ngx_open_file_t *file;
ngx_listening_t *ls, *nls;
ngx_core_conf_t *ccf, *old_ccf;
ngx_core_module_t *module;
char hostname[NGX_MAXHOSTNAMELEN]; ngx_timezone_update(); /* force localtime update with a new timezone */ tp = ngx_timeofday();
tp->sec = ; ngx_time_update(); log = old_cycle->log; pool = ngx_create_pool(NGX_CYCLE_POOL_SIZE, log);
if (pool == NULL) {
return NULL;
}
pool->log = log; cycle = ngx_pcalloc(pool, sizeof(ngx_cycle_t));
if (cycle == NULL) {
ngx_destroy_pool(pool);
return NULL;
} cycle->pool = pool;
cycle->log = log;
cycle->new_log.log_level = NGX_LOG_ERR;
cycle->old_cycle = old_cycle; 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 + );
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 + ); 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;
} n = old_cycle->paths.nelts ? old_cycle->paths.nelts : ; 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 = ;
cycle->paths.size = sizeof(ngx_path_t *);
cycle->paths.nalloc = n;
cycle->paths.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 = ;
} if (ngx_list_init(&cycle->open_files, pool, n, sizeof(ngx_open_file_t))
!= NGX_OK)
{
ngx_destroy_pool(pool);
return NULL;
} 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 = ;
} if (ngx_list_init(&cycle->shared_memory, pool, n, sizeof(ngx_shm_zone_t))
!= NGX_OK)
{
ngx_destroy_pool(pool);
return NULL;
} n = old_cycle->listening.nelts ? old_cycle->listening.nelts : ; 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 = ;
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 (cycle->conf_ctx == NULL) {
ngx_destroy_pool(pool);
return NULL;
} if (gethostname(hostname, NGX_MAXHOSTNAMELEN) == -) {
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 - ] = '\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); for (i = ; 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;
}
} senv = environ; ngx_memzero(&conf, sizeof(ngx_conf_t));
/* STUB: init array ? */
conf.args = ngx_array_create(pool, , 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;
}
//cycle->conf,指向一块内存,多级指针数组,共44个模块。第0个是核心模块的数据结构,ngx_core_module,如后面3.5所示;第3个是一个指向指针的指针,ngx_events_module。
//第六个指向的ngx的http模块,ngx_http_core数据结构,如3.6所示
if (ngx_test_config && !ngx_quiet_mode) {
ngx_log_stderr(, "the configuration file %s syntax is ok", cycle->conf_file.data);
} for (i = ; 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;
}
}
} if (ngx_process == NGX_PROCESS_SIGNALLER) {
return cycle;
} ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); if (ngx_test_config) { if (ngx_create_pidfile(&ccf->pid, log) != NGX_OK) {
goto failed;
} } else if (!ngx_is_init_cycle(old_cycle)) { /*
* we do not create the pid file in the first ngx_init_cycle() call
* because we need to write the demonized process pid
*/ old_ccf = (ngx_core_conf_t *) ngx_get_conf(old_cycle->conf_ctx,
ngx_core_module);
if (ccf->pid.len != old_ccf->pid.len
|| ngx_strcmp(ccf->pid.data, old_ccf->pid.data) != )
{
/* new pid file name */ if (ngx_create_pidfile(&ccf->pid, log) != NGX_OK) {
goto failed;
} ngx_delete_pidfile(old_cycle);
}
} if (ngx_test_lockfile(cycle->lock_file.data, log) != NGX_OK) {
goto failed;
} if (ngx_create_paths(cycle, ccf->user) != NGX_OK) {
goto failed;
} if (cycle->new_log.file == NULL) {
cycle->new_log.file = ngx_conf_open_file(cycle, &error_log);
if (cycle->new_log.file == NULL) {
goto failed;
}
} /* open the new files */ part = &cycle->open_files.part;
file = part->elts; for (i = ; /* void */ ; i++) { if (i >= part->nelts) {
if (part->next == NULL) {
break;
}
part = part->next;
file = part->elts;
i = ;
} if (file[i].name.len == ) {
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, ,
"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) == -) {
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; /* create shared memory */ part = &cycle->shared_memory.part;
shm_zone = part->elts; for (i = ; /* void */ ; i++) { if (i >= part->nelts) {
if (part->next == NULL) {
break;
}
part = part->next;
shm_zone = part->elts;
i = ;
} if (shm_zone[i].shm.size == ) {
ngx_log_error(NGX_LOG_EMERG, log, ,
"zero size shared memory zone \"%V\"",
&shm_zone[i].shm.name);
goto failed;
} shm_zone[i].shm.log = cycle->log; opart = &old_cycle->shared_memory.part;
oshm_zone = opart->elts; for (n = ; /* void */ ; n++) { if (n >= opart->nelts) {
if (opart->next == NULL) {
break;
}
opart = opart->next;
oshm_zone = opart->elts;
n = ;
} if (shm_zone[i].shm.name.len != oshm_zone[n].shm.name.len) {
continue;
} if (ngx_strncmp(shm_zone[i].shm.name.data,
oshm_zone[n].shm.name.data,
shm_zone[i].shm.name.len)
!= )
{
continue;
} if (shm_zone[i].tag == oshm_zone[n].tag
&& shm_zone[i].shm.size == oshm_zone[n].shm.size)
{
shm_zone[i].shm.addr = oshm_zone[n].shm.addr; if (shm_zone[i].init(&shm_zone[i], oshm_zone[n].data)
!= NGX_OK)
{
goto failed;
} goto shm_zone_found;
} ngx_shm_free(&oshm_zone[n].shm); break;
} if (ngx_shm_alloc(&shm_zone[i].shm) != NGX_OK) {
goto failed;
} if (ngx_init_zone_pool(cycle, &shm_zone[i]) != NGX_OK) {
goto failed;
} if (shm_zone[i].init(&shm_zone[i], NULL) != NGX_OK) {
goto failed;
} shm_zone_found: continue;
} /* handle the listening sockets */ if (old_cycle->listening.nelts) {
ls = old_cycle->listening.elts;
for (i = ; i < old_cycle->listening.nelts; i++) {
ls[i].remain = ;
} nls = cycle->listening.elts;
for (n = ; n < cycle->listening.nelts; n++) { for (i = ; i < old_cycle->listening.nelts; i++) {
if (ls[i].ignore) {
continue;
} if (ngx_cmp_sockaddr(nls[n].sockaddr, ls[i].sockaddr) == NGX_OK)
{
nls[n].fd = ls[i].fd;
nls[n].previous = &ls[i];
ls[i].remain = ; if (ls[n].backlog != nls[i].backlog) {
nls[n].listen = ;
} #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER) /*
* FreeBSD, except the most recent versions,
* could not remove accept filter
*/
nls[n].deferred_accept = ls[i].deferred_accept; if (ls[i].accept_filter && nls[n].accept_filter) {
if (ngx_strcmp(ls[i].accept_filter,
nls[n].accept_filter)
!= )
{
nls[n].delete_deferred = ;
nls[n].add_deferred = ;
} } else if (ls[i].accept_filter) {
nls[n].delete_deferred = ; } else if (nls[n].accept_filter) {
nls[n].add_deferred = ;
}
#endif #if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT) if (ls[n].deferred_accept && !nls[n].deferred_accept) {
nls[n].delete_deferred = ; } else if (ls[i].deferred_accept != nls[n].deferred_accept)
{
nls[n].add_deferred = ;
}
#endif
break;
}
} if (nls[n].fd == -) {
nls[n].open = ;
}
} } else {
ls = cycle->listening.elts;
for (i = ; i < cycle->listening.nelts; i++) {
ls[i].open = ;
#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
if (ls[i].accept_filter) {
ls[i].add_deferred = ;
}
#endif
#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
if (ls[i].deferred_accept) {
ls[i].add_deferred = ;
}
#endif
}
} if (ngx_open_listening_sockets(cycle) != NGX_OK) {
goto failed;
} if (!ngx_test_config) {
ngx_configure_listening_sockets(cycle);
} /* commit the new cycle configuration */ if (!ngx_use_stderr && cycle->log->file->fd != ngx_stderr) { if (ngx_set_stderr(cycle->log->file->fd) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
ngx_set_stderr_n " failed");
}
} pool->log = cycle->log; for (i = ; ngx_modules[i]; i++) {
if (ngx_modules[i]->init_module) {
if (ngx_modules[i]->init_module(cycle) != NGX_OK) {
/* fatal */
exit();
}
}
} /* close and delete stuff that lefts from an old cycle */ /* free the unnecessary shared memory */ opart = &old_cycle->shared_memory.part;
oshm_zone = opart->elts; for (i = ; /* void */ ; i++) { if (i >= opart->nelts) {
if (opart->next == NULL) {
goto old_shm_zone_done;
}
opart = opart->next;
oshm_zone = opart->elts;
i = ;
} part = &cycle->shared_memory.part;
shm_zone = part->elts; for (n = ; /* void */ ; n++) { if (n >= part->nelts) {
if (part->next == NULL) {
break;
}
part = part->next;
shm_zone = part->elts;
n = ;
} if (oshm_zone[i].shm.name.len == shm_zone[n].shm.name.len
&& ngx_strncmp(oshm_zone[i].shm.name.data,
shm_zone[n].shm.name.data,
oshm_zone[i].shm.name.len)
== )
{
goto live_shm_zone;
}
} ngx_shm_free(&oshm_zone[i].shm); live_shm_zone: continue;
} old_shm_zone_done: /* close the unnecessary listening sockets */ ls = old_cycle->listening.elts;
for (i = ; i < old_cycle->listening.nelts; i++) { if (ls[i].remain || ls[i].fd == -) {
continue;
} if (ngx_close_socket(ls[i].fd) == -) {
ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
ngx_close_socket_n " listening socket on %V failed",
&ls[i].addr_text);
} #if (NGX_HAVE_UNIX_DOMAIN) if (ls[i].sockaddr->sa_family == AF_UNIX) {
u_char *name; name = ls[i].addr_text.data + sizeof("unix:") - ; ngx_log_error(NGX_LOG_WARN, cycle->log, ,
"deleting socket %s", name); if (ngx_delete_file(name) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno,
ngx_delete_file_n " %s failed", name);
}
} #endif
} /* close the unnecessary open files */ part = &old_cycle->open_files.part;
file = part->elts; for (i = ; /* void */ ; i++) { if (i >= part->nelts) {
if (part->next == NULL) {
break;
}
part = part->next;
file = part->elts;
i = ;
} if (file[i].fd == NGX_INVALID_FILE || file[i].fd == ngx_stderr) {
continue;
} if (ngx_close_file(file[i].fd) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
ngx_close_file_n " \"%s\" failed",
file[i].name.data);
}
} 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;
} if (ngx_temp_pool == NULL) {
ngx_temp_pool = ngx_create_pool(, cycle->log);
if (ngx_temp_pool == NULL) {
ngx_log_error(NGX_LOG_EMERG, cycle->log, ,
"could not create ngx_temp_pool");
exit();
} n = ;
ngx_old_cycles.elts = ngx_pcalloc(ngx_temp_pool,
n * sizeof(ngx_cycle_t *));
if (ngx_old_cycles.elts == NULL) {
exit();
}
ngx_old_cycles.nelts = ;
ngx_old_cycles.size = sizeof(ngx_cycle_t *);
ngx_old_cycles.nalloc = n;
ngx_old_cycles.pool = ngx_temp_pool; ngx_cleaner_event.handler = ngx_clean_old_cycles;
ngx_cleaner_event.log = cycle->log;
ngx_cleaner_event.data = &dumb;
dumb.fd = (ngx_socket_t) -;
} ngx_temp_pool->log = cycle->log; old = ngx_array_push(&ngx_old_cycles);
if (old == NULL) {
exit();
}
*old = old_cycle; if (!ngx_cleaner_event.timer_set) {
ngx_add_timer(&ngx_cleaner_event, );
ngx_cleaner_event.timer_set = ;
} return cycle; failed: if (!ngx_is_init_cycle(old_cycle)) {
old_ccf = (ngx_core_conf_t *) ngx_get_conf(old_cycle->conf_ctx,ngx_core_module);
if (old_ccf->environment) {
environ = old_ccf->environment;
}
} /* rollback the new cycle configuration */ part = &cycle->open_files.part;
file = part->elts; for (i = ; /* void */ ; i++) { if (i >= part->nelts) {
if (part->next == NULL) {
break;
}
part = part->next;
file = part->elts;
i = ;
} if (file[i].fd == NGX_INVALID_FILE || file[i].fd == ngx_stderr) {
continue;
} if (ngx_close_file(file[i].fd) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
ngx_close_file_n " \"%s\" failed",
file[i].name.data);
}
} if (ngx_test_config) {
ngx_destroy_cycle_pools(&conf);
return NULL;
} ls = cycle->listening.elts;
for (i = ; i < cycle->listening.nelts; i++) {
if (ls[i].fd == - || !ls[i].open) {
continue;
} if (ngx_close_socket(ls[i].fd) == -) {
ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
ngx_close_socket_n " %V failed",
&ls[i].addr_text);
}
} ngx_destroy_cycle_pools(&conf); return NULL;
}

修改配置参数之后,可以不重新启动服务,而可以生效。他把所有nginx的参数都放入到一个参数里面,如果修改,那么他会慢慢的修改过来。

3.4 ngx_cycle_s

文件:src/core/ngx_cycle.h

struct ngx_cycle_s {
void ****conf_ctx;//解析配置文件,
ngx_pool_t *pool; ngx_log_t *log;
ngx_log_t new_log; ngx_connection_t **files;
ngx_connection_t *free_connections;
ngx_uint_t free_connection_n; ngx_queue_t reusable_connections_queue; ngx_array_t listening;
ngx_array_t paths;
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;
};

3.5 ngx_core_conf_t 结构体

typedef struct {
ngx_flag_t daemon;
ngx_flag_t master; ngx_msec_t timer_resolution; ngx_int_t worker_processes; //进程数量
ngx_int_t debug_points; ngx_int_t rlimit_nofile;
ngx_int_t rlimit_sigpending;
off_t rlimit_core; int priority; ngx_uint_t cpu_affinity_n;
uint64_t *cpu_affinity; char *username;
ngx_uid_t user;
ngx_gid_t group; ngx_str_t working_directory;
ngx_str_t lock_file; ngx_str_t pid;
ngx_str_t oldpid; ngx_array_t env;
char **environment; #if (NGX_THREADS)
ngx_int_t worker_threads;
size_t thread_stack_size;
#endif } ngx_core_conf_t;

3.6 ngx_http_conf_cxt_t结构体

在src/http/ngx_http_config.h里面

    typedef struct {
void **main_conf; //http的子模块
void **srv_conf; //所有server的参数
void **loc_conf; //所有url的参数
} ngx_http_conf_ctx_t;

NGINX源代码自我总结(一)的更多相关文章

  1. NGINX源代码剖析 之 CPU绑定(CPU亲和性)

    作者:邹祁峰 邮箱:Qifeng.zou.job@gmail.com 博客:http://blog.csdn.net/qifengzou 日期:2014.06.12 18:44 转载请注明来自&quo ...

  2. nginx源代码学习资源(不断更新)

    nginx源代码学习是一个痛苦又快乐的过程,以下列出了一些nginx的学习资源. 首先要做的当然是下载一份nginx源代码,能够从nginx官方站点下载一份最新的. 看了nginx源代码,发现这是一份 ...

  3. 菜鸟nginx源代码剖析数据结构篇(一)动态数组ngx_array_t

    菜鸟nginx源代码剖析数据结构篇(一)动态数组ngx_array_t Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blog.csd ...

  4. 新秀nginx源代码分析数据结构篇(四)红黑树ngx_rbtree_t

    新秀nginx源代码分析数据结构篇(四)红黑树ngx_rbtree_t Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blog.csd ...

  5. 新秀nginx源代码分析数据结构篇(两) 双链表ngx_queue_t

    nginx源代码分析数据结构篇(两) 双链表ngx_queue_t Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blog.csdn. ...

  6. 菜鸟nginx源代码剖析数据结构篇(八) 缓冲区链表ngx_chain_t

    菜鸟nginx源代码剖析数据结构篇(八) 缓冲区链表 ngx_chain_t Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blog. ...

  7. nginx源代码分析之内存池实现原理

    建议看本文档时结合nginx源代码. 1.1   什么是内存池?为什么要引入内存池? 内存池实质上是接替OS进行内存管理.应用程序申请内存时不再与OS打交道.而是从内存池中申请内存或者释放内存到内存池 ...

  8. Nginx源代码分析—业务流程

    Nginx源代码分析-业务流程 到此为止,我们如果ngx_init_cycle已经结束.我们临时无论他做了什么,我们从他做的效果进入. 从常理上来讲,假设一个请求到达,那么我们须要接受这个请求,那么就 ...

  9. 《nginx源代码解析》系列分享专栏

    <nginx源代码解析>系列分享专栏 解析nginx源代码,从main函数开始,一步步解读nginx运行原理,同时进行nginx第三方模块的开发,努力做到知其然,知其所以然 <ngi ...

随机推荐

  1. Linux学习16-CentOS安装gitlab环境

    前言 在学习Gitlab的环境搭建之前,首先需要了解Git,Gitlab,GitHub他们三者之间的关系 Git 它是一个源代码版本控制系统,可让您在本地跟踪更改并从远程资源推送或提取更改. GitH ...

  2. iOS开发UI篇章 15-项目中的常见文件

    iOS开发UI篇-常见的项目文件介绍 一.项目文件结构示意图 二.文件介绍 1.products目录:主要用于mac电脑开发的可运行文件.ios开发用不到这个文件 2.frameworks目录主要用来 ...

  3. 神盾局特工第一季/全集Agents Of SHIELD迅雷下载

    神盾局特工 Agents of S.H.I.E.L.D. (2013) 本季看点:如果你熟悉Marvel漫画或者看过创造电影票房记录的<复仇者联盟>(The Avengers),你应该对「 ...

  4. 详细解读Android中的搜索框(四)—— Searchable配置文件

    <?xml version="1.0" encoding="utf-8"?> <searchable xmlns:android=" ...

  5. Ubuntu下搭建Hyperledger Fabric v1.0环境

      多次尝试才正常启动了Fabric,如遇到各种莫名错误,请参考如下一步步严格安装,特别用户权限需要注意. 一.安装Ubuntu16 虚拟机或双系统,虚拟机有VirtualBox或者VMware,Ub ...

  6. [转]mysql dual虚拟表

    From : http://thobian.info/?p=1035 虚拟表dual 其实我是今天第一次听说,虽然以前有过它的应用.说不定你也用过哦,看这条sql:select sysdate(); ...

  7. 同步一个 fork

    fork 了别人的仓库后,原作者又更新了仓库,如何将自己的代码和原仓库保持一致?本文将给你解答. 如何使用搜索引擎 其实这个问题并不难,我又被坑了.百度搜的东西不靠谱啊,以后这种问题一定要用英文在 G ...

  8. Asp.Net MVC2.0 Url 路由入门---实例篇 【转】

    本篇主要讲述Routing组件的作用,以及举几个实例来学习Asp.Net MVC2.0 Url路由技术. 接着上一篇开始讲,我们在Global.asax中注册一条路由后,我们的请求是怎么转到相应的Vi ...

  9. Libnids(Library Network Intrusion Detection System) .

    Libnids(Library Network Intrusion Detection System)是一个网络入侵检测开发的专业编程接口.它实现了基于网络的入侵检测系统的基本框架,并提供了一些基本的 ...

  10. MFC中如何给静态文本框添加消息响应

    需要两个步骤: 第一个: 是改变它的ID(默认情况下所有的静态文本框的ID都为IDC_STATIC,你需要改变他的ID为其他的值). 第二个: 是在它的属性对话框中选中Notify选项,VS是将该属性 ...