nginx 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; ngx_debug_init(); if (ngx_strerror_init() != NGX_OK) {
return ;
} if (ngx_get_options(argc, argv) != NGX_OK) {
return ;
} if (ngx_show_version) {
ngx_write_stderr("nginx version: " NGINX_VER NGX_LINEFEED); if (ngx_show_help) {
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);
#endif /*
* init_cycle->log is required for signal handlers and
* ngx_process_options()
*/ ngx_memzero(&init_cycle, sizeof(ngx_cycle_t));
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 ;
} 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 ;
}
ngx_debug_init();
ngx_linux_config.h文件中定义:
#define NGX_HAVE_OS_SPECIFIC_INIT 1
#define ngx_debug_init()
其实什么也没做。
ngx_strerror_init();//初始化了*ngx_sys_errlist 这个全局静态变量,以供ngx_strerror使用
static ngx_str_t *ngx_sys_errlist;
static ngx_str_t ngx_unknown_error = ngx_string("Unknown error"); u_char *
ngx_strerror(ngx_err_t err, u_char *errstr, size_t size)
{
ngx_str_t *msg; msg = ((ngx_uint_t) err < NGX_SYS_NERR) ? &ngx_sys_errlist[err]:
&ngx_unknown_error;
size = ngx_min(size, msg->len); return ngx_cpymem(errstr, msg->data, size);
}
ngx_get_options(argc, argv);//设置命令行参数
static ngx_int_t
ngx_get_options(int argc, char *const *argv)
{
u_char *p;
ngx_int_t i; for (i = ; i < argc; i++) { p = (u_char *) argv[i]; if (*p++ != '-') {
ngx_log_stderr(, "invalid option: \"%s\"", argv[i]);
return NGX_ERROR;
} while (*p) { switch (*p++) { case '?':
case 'h':
ngx_show_version = ;
ngx_show_help = ;
break; case 'v':
ngx_show_version = ;
break; case 'V':
ngx_show_version = ;
ngx_show_configure = ;
break; case 't':
ngx_test_config = ;
break; case 'q':
ngx_quiet_mode = ;
break; case 'p':
if (*p) {
ngx_prefix = p;
goto next;
} if (argv[++i]) {
ngx_prefix = (u_char *) argv[i];
goto next;
} ngx_log_stderr(, "option \"-p\" requires directory name");
return NGX_ERROR; case 'c':
if (*p) {
ngx_conf_file = p;
goto next;
} if (argv[++i]) {
ngx_conf_file = (u_char *) argv[i];
goto next;
} ngx_log_stderr(, "option \"-c\" requires file name");
return NGX_ERROR; case 'g':
if (*p) {
ngx_conf_params = p;
goto next;
} if (argv[++i]) {
ngx_conf_params = (u_char *) argv[i];
goto next;
} ngx_log_stderr(, "option \"-g\" requires parameter");
return NGX_ERROR; break; case 'V':
ngx_show_version = ;
ngx_show_configure = ;
break; case 't':
ngx_test_config = ;
break; case 'q':
ngx_quiet_mode = ;
break; case 'p':
if (*p) {
ngx_prefix = p;
goto next;
} if (argv[++i]) {
ngx_prefix = (u_char *) argv[i];
goto next;
} ngx_log_stderr(, "option \"-p\" requires directory name");
return NGX_ERROR; case 'c':
if (*p) {
ngx_conf_file = p;
goto next;
} if (argv[++i]) {
ngx_conf_file = (u_char *) argv[i];
goto next;
} ngx_log_stderr(, "option \"-c\" requires file name");
return NGX_ERROR; case 'g':
if (*p) {
ngx_conf_params = p;
goto next;
} if (argv[++i]) {
ngx_conf_params = (u_char *) argv[i];
goto next;
} ngx_log_stderr(, "option \"-g\" requires parameter");
return NGX_ERROR; case 's':
if (*p) {
if (argv[++i]) {
ngx_conf_params = (u_char *) argv[i];
goto next;
} ngx_log_stderr(, "option \"-g\" requires parameter");
return NGX_ERROR; case 's':
if (*p) {
ngx_signal = (char *) p; } else if (argv[++i]) {
ngx_signal = argv[i]; } else {
ngx_log_stderr(, "option \"-s\" requires parameter");
return NGX_ERROR;
} if (ngx_strcmp(ngx_signal, "stop") ==
|| ngx_strcmp(ngx_signal, "quit") ==
|| ngx_strcmp(ngx_signal, "reopen") ==
|| ngx_strcmp(ngx_signal, "reload") == )
{
ngx_process = NGX_PROCESS_SIGNALLER;
goto next;
} ngx_log_stderr(, "invalid option: \"-s %s\"", ngx_signal);
return NGX_ERROR; default:
ngx_log_stderr(, "invalid option: \"%c\"", *(p - ));
return NGX_ERROR;
}
} next: continue;
} return NGX_OK;
}
ngx_max_sockets = -
ngx_time_init();
void
ngx_time_init(void)
{
ngx_cached_err_log_time.len = sizeof("1970/09/28 12:00:00") - ;
ngx_cached_http_time.len = sizeof("Mon, 28 Sep 1970 06:00:00 GMT") - ;
ngx_cached_http_log_time.len = sizeof("28/Sep/1970:12:00:00 +0600") - ;
ngx_cached_http_log_iso8601.len = sizeof("1970-09-28T12:00:00+06:00") - ; ngx_cached_time = &cached_time[]; ngx_time_update();
}
log = ngx_log_init(ngx_prefix);
ngx_log_file.fd = ngx_open_file(name, NGX_FILE_APPEND,
NGX_FILE_CREATE_OR_OPEN,
NGX_FILE_DEFAULT_ACCESS); if (ngx_log_file.fd == NGX_INVALID_FILE) {
ngx_log_stderr(ngx_errno,
"[alert] could not open error log file: "
ngx_open_file_n " \"%s\" failed", name);
#if (NGX_WIN32)
ngx_event_log(ngx_errno,
"could not open error log file: "
ngx_open_file_n " \"%s\" failed", name);
#endif ngx_log_file.fd = ngx_stderr;
}
if (ngx_os_init(log) != NGX_OK) {
return ;
}
ngx_int_t
ngx_os_init(ngx_log_t *log)
{
ngx_uint_t n; #if (NGX_HAVE_OS_SPECIFIC_INIT)
if (ngx_os_specific_init(log) != NGX_OK) {
return NGX_ERROR;
}
#endif ngx_init_setproctitle(log); ngx_pagesize = getpagesize();
ngx_cacheline_size = NGX_CPU_CACHE_LINE; for (n = ngx_pagesize; n >>= ; ngx_pagesize_shift++) { /* void */ } #if (NGX_HAVE_SC_NPROCESSORS_ONLN)
if (ngx_ncpu == ) {
ngx_ncpu = sysconf(_SC_NPROCESSORS_ONLN);
}
#endif if (ngx_ncpu < ) {
ngx_ncpu = ;
} ngx_cpuinfo(); if (getrlimit(RLIMIT_NOFILE, &rlmt) == -) {
ngx_log_error(NGX_LOG_ALERT, log, errno,
"getrlimit(RLIMIT_NOFILE) failed)");
return NGX_ERROR;
} ngx_max_sockets = (ngx_int_t) rlmt.rlim_cur; //最大打开文件数 #if (NGX_HAVE_INHERITED_NONBLOCK || NGX_HAVE_ACCEPT4)
ngx_inherited_nonblocking = ;
#else
ngx_inherited_nonblocking = ;
#endif srandom(ngx_time()); return NGX_OK;
}
cycle = ngx_init_cycle(&init_cycle);
#ifndef NGX_CYCLE_POOL_SIZE
#define NGX_CYCLE_POOL_SIZE NGX_DEFAULT_POOL_SIZE
#endif #define NGX_MAX_ALLOC_FROM_POOL (ngx_pagesize - 1) #define NGX_DEFAULT_POOL_SIZE (16 * 1024) #define NGX_POOL_ALIGNMENT 16
#define NGX_MIN_POOL_SIZE \
ngx_align((sizeof(ngx_pool_t) + * sizeof(ngx_pool_large_t)), \
NGX_POOL_ALIGNMENT)
ngx_init_cycle()分析
初始化过程如下。
- 调用ngx_timezone_update()更新时区,调用ngx_time_update()更新时间
- 创建大小为NGX_CYCLE_POOL_SIZE=16384B的内存池,并从中分配ngx_cycle_t结构
- 简单初始化,如记录pool指针、log指针
- 初始化配置前缀、前缀、配置文件、配置参数等字符串
- 初始化pathes数组
- 初始化open_files链表
- 初始化shared_memory链表
- 初始化listening数组
- 初始化resuable_connections_queue队列
- 从pool为conf_ctx分配空间
- 初始化hostname字符串
- 调用core模块的create_conf()
- 配置文件解析
- 调用core模块的init_conf()
- 遍历open_files链表中的每一个文件并打开
- 创建共享内存并初始化(新旧shared_memory链表的比较,相同的共享内存保留,旧的不同的共享内存被释放,新的被创建)
- (尝试5遍)遍历listening数组并打开所有侦听sockets(socket()->setsockopt()->bind()->listen())
- 提交新的cycle配置,并调用所有模块的init_module(实际上只有ngx_event_core_module模块定义了该callback,即只有ngx_event_module_init()被调用)
- 关闭或删除残留在old_cycle中的资源
- 释放多余的共享内存
- 关闭多余的侦听sockets
- 关闭多余的打开文件
struct ngx_listening_s {
ngx_socket_t fd; struct sockaddr *sockaddr;
socklen_t socklen; /* size of sockaddr */
size_t addr_text_max_len;
ngx_str_t addr_text; int type; int backlog;
int rcvbuf;
int sndbuf;
#if (NGX_HAVE_KEEPALIVE_TUNABLE)
int keepidle;
int keepintvl;
int keepcnt;
#endif /* handler of accepted connection */
ngx_connection_handler_pt handler; void *servers; /* array of ngx_http_in_addr_t, for example */ ngx_log_t log;
ngx_log_t *logp; size_t pool_size;
/* should be here because of the AcceptEx() preread */
size_t post_accept_buffer_size;
/* should be here because of the deferred accept */
ngx_msec_t post_accept_timeout;
/* should be here because of the AcceptEx() preread */
size_t post_accept_buffer_size;
size_t post_accept_buffer_size;
/* should be here because of the deferred accept */
ngx_msec_t post_accept_timeout; ngx_listening_t *previous;
ngx_connection_t *connection; unsigned open:;
unsigned remain:;
unsigned ignore:; unsigned bound:; /* already bound */
unsigned inherited:; /* inherited from previous process */
unsigned nonblocking_accept:;
unsigned listen:;
unsigned nonblocking:;
unsigned shared:; /* shared between threads or processes */
unsigned addr_ntop:; #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
unsigned ipv6only:;
#endif
unsigned keepalive:; #if (NGX_HAVE_DEFERRED_ACCEPT)
unsigned deferred_accept:;
unsigned delete_deferred:;
unsigned add_deferred:;
#ifdef SO_ACCEPTFILTER
char *accept_filter;
#endif
#endif
#if (NGX_HAVE_SETFIB)
int setfib;
#endif };
p *ngx_cycle
$ = {
conf_ctx = 0x6a1d10,
pool = 0x6a0f30,
log = 0x6a0f98,
new_log = {
log_level = ,
file = 0x6a11d8,
connection = ,
handler = ,
data = 0x0,
action = 0x0
},
files = 0x0,
free_connections = 0x0,
free_connection_n = ,
reusable_connections_queue = {
prev = 0x6a0fe0,
next = 0x6a0fe0
},
listening = {
elts = 0x6a1540,
nelts = ,
size = ,
nalloc = ,
pool = 0x6a0f30
},
paths = {
elts = 0x6a1188,
nelts = ,
size = ,
nalloc = ,
pool = 0x6a0f30
},
open_files = {
last = 0x6a1048,
part = {
elts = 0x6a11d8,
---Type <return> to continue, or q <return> to quit---
nelts = ,
next = 0x0
},
size = ,
nalloc = ,
pool = 0x6a0f30
},
shared_memory = {
last = 0x6a1080,
part = {
elts = 0x6a14f8,
nelts = ,
next = 0x0
},
size = ,
nalloc = ,
pool = 0x6a0f30
},
connection_n = ,
files_n = ,
connections = 0x0,
read_events = 0x0,
write_events = 0x0,
old_cycle = 0x0,
conf_file = {
len = ,
data = 0x6a1167 "/usr/local/nginx/conf/nginx.conf"
},
conf_param = {
len = ,
data = 0x6a1188 "\370\030l"
},
conf_prefix = {
len = ,
data = 0x6a1140 "/usr/local/nginx/conf//usr/local/nginx//usr/local/nginx/conf/nginx.conf"
},
prefix = {
---Type <return> to continue, or q <return> to quit---
len = ,
data = 0x6a1156 "/usr/local/nginx//usr/local/nginx/conf/nginx.conf"
},
lock_file = {
len = ,
data = 0x6c60a0 "/usr/local/nginx/logs/nginx.lock.accept"
},
hostname = {
len = ,
data = 0x6a1e88 "centos"
}
}
typedef struct {
int signo;
char *signame;
char *name;
void (*handler)(int signo);
} ngx_signal_t;
if (!ngx_inherited && ccf->daemon) {
if (ngx_daemon(cycle->log) != NGX_OK) {
return ;
} ngx_daemonized = ;
}
ngx_int_t
ngx_daemon(ngx_log_t *log)
{
int fd; switch (fork()) {
case -:
ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "fork() failed");
return NGX_ERROR; case :
break; default:
exit();
} ngx_pid = ngx_getpid(); if (setsid() == -) {
ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "setsid() failed");
return NGX_ERROR;
} umask(); fd = open("/dev/null", O_RDWR);
if (fd == -) {
ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
"open(\"/dev/null\") failed");
return NGX_ERROR;
} if (dup2(fd, STDIN_FILENO) == -) {
ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "dup2(STDIN) failed");
return NGX_ERROR;
if (dup2(fd, STDOUT_FILENO) == -1) {
ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "dup2(STDOUT) failed");
return NGX_ERROR;
}
#if 0
if (dup2(fd, STDERR_FILENO) == -1) {
ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "dup2(STDERR) failed");
return NGX_ERROR;
}
#endif
if (fd > STDERR_FILENO) {
if (close(fd) == -1) {
ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "close() failed");
return NGX_ERROR;
}
}
return NGX_OK;
}
if (ngx_process == NGX_PROCESS_SINGLE) {
ngx_single_process_cycle(cycle); } else {
ngx_master_process_cycle(cycle);
} return ;
void
ngx_master_process_cycle(ngx_cycle_t *cycle)
{
char *title;
u_char *p;
size_t size;
ngx_int_t i;
ngx_uint_t n, sigio;
sigset_t set;
struct itimerval itv;
ngx_uint_t live;
ngx_msec_t delay;
ngx_listening_t *ls;
ngx_core_conf_t *ccf; sigemptyset(&set);
sigaddset(&set, SIGCHLD);
sigaddset(&set, SIGALRM);
sigaddset(&set, SIGIO);
sigaddset(&set, SIGINT);
sigaddset(&set, ngx_signal_value(NGX_RECONFIGURE_SIGNAL));
sigaddset(&set, ngx_signal_value(NGX_REOPEN_SIGNAL));
sigaddset(&set, ngx_signal_value(NGX_NOACCEPT_SIGNAL));
sigaddset(&set, ngx_signal_value(NGX_TERMINATE_SIGNAL));
sigaddset(&set, ngx_signal_value(NGX_SHUTDOWN_SIGNAL));
sigaddset(&set, ngx_signal_value(NGX_CHANGEBIN_SIGNAL)); if (sigprocmask(SIG_BLOCK, &set, NULL) == -) {
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
"sigprocmask() failed");
} sigemptyset(&set); size = sizeof(master_process); for (i = ; i < ngx_argc; i++) {
sigaddset(&set, SIGIO);
sigaddset(&set, SIGINT);
sigaddset(&set, ngx_signal_value(NGX_RECONFIGURE_SIGNAL));
sigaddset(&set, ngx_signal_value(NGX_REOPEN_SIGNAL));
sigaddset(&set, ngx_signal_value(NGX_NOACCEPT_SIGNAL));
sigaddset(&set, ngx_signal_value(NGX_TERMINATE_SIGNAL));
sigaddset(&set, ngx_signal_value(NGX_SHUTDOWN_SIGNAL));
sigaddset(&set, ngx_signal_value(NGX_CHANGEBIN_SIGNAL)); if (sigprocmask(SIG_BLOCK, &set, NULL) == -) {
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
"sigprocmask() failed");
} sigemptyset(&set); size = sizeof(master_process); for (i = ; i < ngx_argc; i++) {
size += ngx_strlen(ngx_argv[i]) + ;
} title = ngx_pnalloc(cycle->pool, size); p = ngx_cpymem(title, master_process, sizeof(master_process) - );
for (i = ; i < ngx_argc; i++) {
*p++ = ' ';
p = ngx_cpystrn(p, (u_char *) ngx_argv[i], size);
} ngx_setproctitle(title); ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); ngx_start_worker_processes(cycle, ccf->worker_processes,
NGX_PROCESS_RESPAWN);
ngx_start_cache_manager_processes(cycle, ); ngx_new_binary = ;
delay = ;
sigio = ;
live = ; for ( ;; ) {
if (delay) {
if (ngx_sigalrm) {
sigio = ;
delay *= ;
ngx_sigalrm = ;
} ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, ,
"termination cycle: %d", delay); itv.it_interval.tv_sec = ;
itv.it_interval.tv_usec = ;
itv.it_value.tv_sec = delay / ;
itv.it_value.tv_usec = (delay % ) * ; if (setitimer(ITIMER_REAL, &itv, NULL) == -) {
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
"setitimer() failed");
}
} ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, , "sigsuspend"); sigsuspend(&set); ngx_time_update(); ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, ,
"wake up, sigio %i", sigio); if (ngx_reap) {
ngx_reap = ;
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, , "reap children"); live = ngx_reap_children(cycle);
} if (!live && (ngx_terminate || ngx_quit)) {
ngx_master_process_exit(cycle);
} if (ngx_terminate) {
if (delay == ) {
delay = ;
} if (sigio) {
sigio--;
continue;
} sigio = ccf->worker_processes + /* cache processes */; if (delay > ) {
ngx_signal_worker_processes(cycle, SIGKILL);
} else {
ngx_signal_worker_processes(cycle,
ngx_signal_value(NGX_TERMINATE_SIGNAL));
} continue;
} if (ngx_quit) {
ngx_signal_worker_processes(cycle,
ngx_signal_value(NGX_SHUTDOWN_SIGNAL)); ls = cycle->listening.elts;
for (n = ; n < cycle->listening.nelts; n++) {
if (ngx_close_socket(ls[n].fd) == -) {
ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno,
ngx_close_socket_n " %V failed",
&ls[n].addr_text);
}
}
cycle->listening.nelts = ; continue;
} if (ngx_reconfigure) {
ngx_reconfigure = ; if (ngx_new_binary) {
ngx_start_worker_processes(cycle, ccf->worker_processes,
NGX_PROCESS_RESPAWN);
ngx_start_cache_manager_processes(cycle, );
ngx_noaccepting = ; continue;
} ngx_log_error(NGX_LOG_NOTICE, cycle->log, , "reconfiguring"); cycle = ngx_init_cycle(cycle);
if (cycle == NULL) {
cycle = (ngx_cycle_t *) ngx_cycle;
continue;
} ngx_cycle = cycle;
ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx,
ngx_core_module);
ngx_start_worker_processes(cycle, ccf->worker_processes,
NGX_PROCESS_JUST_RESPAWN);
ngx_start_cache_manager_processes(cycle, ); /* allow new processes to start */
ngx_msleep(); live = ;
ngx_signal_worker_processes(cycle,
ngx_signal_value(NGX_SHUTDOWN_SIGNAL));
ngx_msleep(); live = ;
ngx_signal_worker_processes(cycle,
ngx_signal_value(NGX_SHUTDOWN_SIGNAL));
} if (ngx_restart) {
ngx_restart = ;
ngx_start_worker_processes(cycle, ccf->worker_processes,
NGX_PROCESS_RESPAWN);
ngx_start_cache_manager_processes(cycle, );
live = ;
} if (ngx_reopen) {
ngx_reopen = ;
ngx_log_error(NGX_LOG_NOTICE, cycle->log, , "reopening logs");
ngx_reopen_files(cycle, ccf->user);
ngx_signal_worker_processes(cycle,
ngx_signal_value(NGX_REOPEN_SIGNAL));
} if (ngx_change_binary) {
ngx_change_binary = ;
ngx_log_error(NGX_LOG_NOTICE, cycle->log, , "changing binary");
ngx_new_binary = ngx_exec_new_binary(cycle, ngx_argv);
} if (ngx_noaccept) {
ngx_noaccept = ;
ngx_noaccepting = ;
ngx_signal_worker_processes(cycle,
ngx_signal_value(NGX_SHUTDOWN_SIGNAL));
}
}
}
static voidngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n, ngx_int_t type)
{
ngx_int_t i;
ngx_channel_t ch; ngx_log_error(NGX_LOG_NOTICE, cycle->log, , "start worker processes"); ch.command = NGX_CMD_OPEN_CHANNEL; for (i = ; i < n; i++) { ngx_spawn_process(cycle, ngx_worker_process_cycle,
(void *) (intptr_t) i, "worker process", type); ch.pid = ngx_processes[ngx_process_slot].pid;
ch.slot = ngx_process_slot;
ch.fd = ngx_processes[ngx_process_slot].channel[]; ngx_pass_open_channel(cycle, &ch);
}
}
nginx main函数的更多相关文章
- 菜鸟nginx源码剖析 框架篇(一) 从main函数看nginx启动流程(转)
俗话说的好,牵牛要牵牛鼻子 驾车顶牛,处理复杂的东西,只要抓住重点,才能理清脉络,不至于深陷其中,不能自拔.对复杂的nginx而言,main函数就是“牛之鼻”,只要能理清main函数,就一定能理解其中 ...
- 菜鸟nginx源代码剖析 框架篇(一) 从main函数看nginx启动流程
菜鸟nginx源代码剖析 框架篇(一) 从main函数看nginx启动流程 Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blog.c ...
- [C#] 了解过入口函数 Main() 吗?带你用批处理玩转 Main 函数
了解过入口函数 Main() 吗?带你用批处理玩转 Main 函数 目录 简介 特点 方法的参数 方法的返回值 与批处理交互的一个示例 简介 我们知道,新建一个控制台应用程序的时候,IDE 会同时创建 ...
- 选择目录,选择文件夹的COM组件问题。在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式。请确保您的 Main 函数带有 STAThreadAttribute 标记。 只有将调试器附加到该进程才会引发此异常。
异常: 在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式.请确保您的 Main 函数带有 STAThreadAttribute 标记. 只有将调试器附加到该进程才会引发此异常. ...
- eclipse的maven项目,如何使用java run main函数
项目使用maven管理,一般说来就使用jetty:run了.但是对于做功能测试和集成测试的用例,需要使用自定义的quickrun来运行进行测试环境的参数设定和功能隔离,google一番发现maven有 ...
- [汇编与C语言关系]2. main函数与启动例程
为什么汇编程序的入口是_start,而C程序的入口是main函数呢?以下就来解释这个问题 在<x86汇编程序基础(AT&T语法)>一文中我们汇编和链接的步骤是: $ as hell ...
- 【Go入门教程3】流程(if、goto、for、switch)和函数(多个返回值、变参、传值与传指针、defer、函数作为值/类型、Panic和Recover、main函数和init函数、import)
这小节我们要介绍Go里面的流程控制以及函数操作. 流程控制 流程控制在编程语言中是最伟大的发明了,因为有了它,你可以通过很简单的流程描述来表达很复杂的逻辑.Go中流程控制分三大类:条件判断,循环控制和 ...
- linux c 笔记-2 Hello World & main函数
按照惯例撸一个hello_world.c #include <stdio.h> int main(int argc, char * argv[]) { printf("hello ...
- Spark&Hadoop:scala编写spark任务jar包,运行无法识别main函数,怎么办?
昨晚和同事一起看一个scala写的程序,程序都写完了,且在idea上debug运行是ok的.但我们不能调试的方式部署在客户机器上,于是打包吧.打包时,我们是采用把外部引入的五个包(spark-asse ...
随机推荐
- H.264的码率控制:CBR和VBR
CBR: Constants Bits Rate, 静态比特率. 比特率在流的进行过程中基本保持恒定并且接近目标比特率,当对复杂内容编码时质量会下降. 在流式播放方案中使用CBR编码最为有效;优点是带 ...
- Gradle Goodness: Copy Files with Filtering
Gradle Goodness: Copy Files with Filtering Gradle's copy task is very powerful and includes filterin ...
- win7在安装时跳过输入用户名界面,直接开启管理员用户
WIN7原版系统安装完后需要创建用户,为了追求纯净简化不必要的步骤,可以选择跳过创建用户直接启用内置管理员账户.首先,到了创建用户这一步先别急着往下点,此时按键盘的SHIFT + F10 组合键调出命 ...
- node引入bootstrap npm报错
今天node引入bootstrap npm报错 但是页面正常显示 最后发现bootstrap.min.js.map没有放在文件里 虽然不用页面中引入 另外也发现了怎么看这种错误了
- ABAP术语-Update Key
Update Key 原文:http://www.cnblogs.com/qiangsheng/archive/2008/03/20/1114171.html Unique character str ...
- IDEA导入eclipse项目并部署到tomcat
1.首先引入本地项目 我这里是maven项目就直接选择的以maven项目引入,如果选eclipse的话,pom文件不会被初始化,部署tomcat会出问题 这项选完后,就一路next,jdk可以在引入的 ...
- jQuery实现页面回到顶部功能
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...
- [笔记] 升級到 Delphi 10.2 Tokyo 笔记
升級到 Delphi 10.2 Tokyo 笔记: 更新 Xcode 8.3 & iOS 10.3 测试: macOS 没问题(可 Debug) iOS Simulator 没问题(可 Deb ...
- 2.Hadoop集群安装进阶
Hadoop进阶 1.配置SSH免密 (1)修改slaves文件 切换到master机器,本节操作全在master进行. 进入/usr/hadoop/etc/hadoop目录下,找到slaves文件, ...
- [Golang学习笔记] 09 字典
字典(Map):map[K]T K:为键类型,T:为元素(值)类型.例:map[int] string 一个键类型为int,值类型为string的字典类型 Go语言的字典类型(map)实际上是一个哈希 ...