# HG changeset patch # User Igor Sysoev # Date 1073595726 0 # Node ID 99df0edb63ed89c3a4346b7f38b4637cecad9eea # Parent 401154e2182670668c8b16526f2e31230ab46623 nginx-0.0.1-2004-01-09-00:02:06 import diff --git a/src/core/nginx.c b/src/core/nginx.c --- a/src/core/nginx.c +++ b/src/core/nginx.c @@ -10,6 +10,7 @@ typedef struct { int daemon; int master; ngx_str_t pid; + ngx_str_t newpid; } ngx_core_conf_t; @@ -74,11 +75,11 @@ uid_t user; u_int ngx_connection_counter; ngx_int_t ngx_process; - - +ngx_int_t ngx_inherited; ngx_int_t ngx_reap; ngx_int_t ngx_terminate; ngx_int_t ngx_quit; +ngx_int_t ngx_pause; ngx_int_t ngx_reconfigure; ngx_int_t ngx_reopen; ngx_int_t ngx_change_binary; @@ -191,11 +192,13 @@ int main(int argc, char *const *argv, ch if (ccf->pid.len == 0) { ccf->pid.len = sizeof(NGINX_PID) - 1; ccf->pid.data = NGINX_PID; + ccf->newpid.len = sizeof(NGINX_NEW_PID) - 1; + ccf->newpid.data = NGINX_NEW_PID; } len = ngx_snprintf(pid, /* STUB */ 10, PID_T_FMT, ngx_getpid()); ngx_memzero(&ctx.pid, sizeof(ngx_file_t)); - ctx.pid.name = ccf->pid; + ctx.pid.name = ngx_inherited ? ccf->newpid : ccf->pid; ctx.pid.fd = ngx_open_file(ctx.pid.name.data, NGX_FILE_RDWR, NGX_FILE_CREATE_OR_OPEN); @@ -229,7 +232,7 @@ static void ngx_master_process_cycle(ngx { ngx_msec_t delay; struct timeval tv; - ngx_int_t i; + ngx_uint_t i, live; sigset_t set, wset; delay = 1000; @@ -238,7 +241,7 @@ static void ngx_master_process_cycle(ngx sigaddset(&set, SIGCHLD); sigaddset(&set, ngx_signal_value(NGX_RECONFIGURE_SIGNAL)); sigaddset(&set, ngx_signal_value(NGX_REOPEN_SIGNAL)); - sigaddset(&set, ngx_signal_value(NGX_INTERRUPT_SIGNAL)); + sigaddset(&set, ngx_signal_value(NGX_PAUSE_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)); @@ -290,7 +293,12 @@ static void ngx_master_process_cycle(ngx ngx_process_events(cycle->log); - } else if (ngx_process == NGX_PROCESS_MASTER_QUIT) { + } else if (ngx_process == NGX_PROCESS_QUITING + || ngx_process == NGX_PROCESS_PAUSED) + { + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, + "quit cycle"); + if (delay < 10000) { delay *= 2; } @@ -301,42 +309,75 @@ static void ngx_master_process_cycle(ngx continue; } - ngx_msleep(delay); + if (ngx_reap == 0) { + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, + "sleep %d", delay / 1000); + + ngx_msleep(delay); - ngx_gettimeofday(&tv); - ngx_time_update(tv.tv_sec); + ngx_gettimeofday(&tv); + ngx_time_update(tv.tv_sec); + + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, + "wake up"); + } if (sigprocmask(SIG_BLOCK, &set, NULL) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "sigprocmask() failed"); } + + if (ngx_reap) { + ngx_reap = 0; + + live = 0; + for (i = 0; i < ngx_last_process; i++) { + if (ngx_processes[i].exiting + && !ngx_processes[i].exited) + { + live = 1; + continue; + } + + if (i != --ngx_last_process) { + ngx_processes[i--] = + ngx_processes[ngx_last_process]; + } + } + + if (live == 0 && ngx_process == NGX_PROCESS_QUITING) { + if (ngx_delete_file(ctx->pid.name.data) + == NGX_FILE_ERROR) + { + ngx_log_error(NGX_LOG_ALERT, cycle->log, + ngx_errno, + ngx_delete_file_n + " \"%s\" failed", + ctx->pid.name.data); + } + + ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "exit"); + exit(0); + } + } } - if (ngx_quit || ngx_terminate) { -#if !(WIN32) - if (ngx_delete_file(ctx->pid.name.data) == NGX_FILE_ERROR) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - ngx_delete_file_n " \"%s\" failed", - ctx->pid.name.data); - } -#endif - - ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "exiting"); + if (ngx_terminate) { + ngx_signal_processes(cycle, + ngx_signal_value(NGX_TERMINATE_SIGNAL)); + ngx_process = NGX_PROCESS_QUITING; + } - if (ngx_process == NGX_PROCESS_MASTER) { - ngx_signal_processes(cycle, + if (ngx_quit) { + ngx_signal_processes(cycle, ngx_signal_value(NGX_SHUTDOWN_SIGNAL)); - - /* TODO: wait workers */ + ngx_process = NGX_PROCESS_QUITING; + } - ngx_msleep(1000); - - ngx_gettimeofday(&tv); - ngx_time_update(tv.tv_sec); - } - - ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "exit"); - exit(0); + if (ngx_pause || ngx_process != NGX_PROCESS_PAUSED) { + ngx_signal_processes(cycle, + ngx_signal_value(NGX_SHUTDOWN_SIGNAL)); + ngx_process = NGX_PROCESS_PAUSED; } if (ngx_reap) { @@ -349,8 +390,6 @@ static void ngx_master_process_cycle(ngx ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "changing binary"); ngx_exec_new_binary(cycle, ctx->argv); - - /* TODO: quit workers */ } if (ngx_reconfigure) { @@ -367,13 +406,20 @@ static void ngx_master_process_cycle(ngx } - cycle = ngx_init_cycle(cycle); - if (cycle == NULL) { - cycle = (ngx_cycle_t *) ngx_cycle; - continue; + if (ngx_pause) { + ngx_pause = 0; + ngx_process = NGX_PROCESS_MASTER; + + } else { + cycle = ngx_init_cycle(cycle); + if (cycle == NULL) { + cycle = (ngx_cycle_t *) ngx_cycle; + continue; + } + + ngx_cycle = cycle; } - ngx_cycle = cycle; ngx_reconfigure = 0; break; } @@ -388,6 +434,7 @@ static void ngx_worker_process_cycle(ngx ngx_listening_t *ls; ngx_process = NGX_PROCESS_WORKER; + ngx_last_process = 0; if (user) { if (setuid(user) == -1) { @@ -502,6 +549,8 @@ static ngx_int_t ngx_add_inherited_socke } } + ngx_inherited = 1; + return ngx_set_inherited_sockets(cycle); } diff --git a/src/core/nginx.h b/src/core/nginx.h --- a/src/core/nginx.h +++ b/src/core/nginx.h @@ -5,6 +5,7 @@ #define NGINX_VER "nginx/0.0.1" #define NGINX_CONF "nginx.conf" #define NGINX_PID "nginx.pid" +#define NGINX_NEW_PID NGINX_PID ".newbin" #define NGINX_VAR "NGINX=" #define NGINX_VAR_LEN (sizeof(NGINX_VAR) - 1) diff --git a/src/core/ngx_config.h b/src/core/ngx_config.h --- a/src/core/ngx_config.h +++ b/src/core/ngx_config.h @@ -63,11 +63,11 @@ typedef u_int ngx_uint_t; #define ngx_signal_value(n) ngx_signal_helper(n) /* TODO: #ifndef */ +#define NGX_SHUTDOWN_SIGNAL QUIT +#define NGX_TERMINATE_SIGNAL TERM +#define NGX_PAUSE_SIGNAL INT #define NGX_RECONFIGURE_SIGNAL HUP #define NGX_REOPEN_SIGNAL USR1 -#define NGX_SHUTDOWN_SIGNAL QUIT -#define NGX_TERMINATE_SIGNAL TERM -#define NGX_INTERRUPT_SIGNAL INT #define NGX_CHANGEBIN_SIGNAL USR2 #endif diff --git a/src/os/unix/ngx_os.h b/src/os/unix/ngx_os.h --- a/src/os/unix/ngx_os.h +++ b/src/os/unix/ngx_os.h @@ -54,6 +54,7 @@ extern ngx_int_t ngx_process; extern ngx_int_t ngx_reap; extern ngx_int_t ngx_quit; extern ngx_int_t ngx_terminate; +extern ngx_int_t ngx_pause; extern ngx_int_t ngx_reconfigure; extern ngx_int_t ngx_reopen; extern ngx_int_t ngx_change_binary; diff --git a/src/os/unix/ngx_posix_init.c b/src/os/unix/ngx_posix_init.c --- a/src/os/unix/ngx_posix_init.c +++ b/src/os/unix/ngx_posix_init.c @@ -13,7 +13,6 @@ void ngx_signal_handler(int signo); typedef struct { int signo; char *signame; - char *action; void (*handler)(int signo); } ngx_signal_t; @@ -21,39 +20,33 @@ typedef struct { ngx_signal_t signals[] = { { ngx_signal_value(NGX_RECONFIGURE_SIGNAL), "SIG" ngx_value(NGX_RECONFIGURE_SIGNAL), - ", reconfiguring", ngx_signal_handler }, { ngx_signal_value(NGX_REOPEN_SIGNAL), "SIG" ngx_value(NGX_REOPEN_SIGNAL), - ", reopen logs", ngx_signal_handler }, - { ngx_signal_value(NGX_INTERRUPT_SIGNAL), - "SIG" ngx_value(NGX_INTERRUPT_SIGNAL), - ", exiting", + { ngx_signal_value(NGX_PAUSE_SIGNAL), + "SIG" ngx_value(NGX_PAUSE_SIGNAL), ngx_signal_handler }, { ngx_signal_value(NGX_TERMINATE_SIGNAL), "SIG" ngx_value(NGX_TERMINATE_SIGNAL), - ", exiting", ngx_signal_handler }, { ngx_signal_value(NGX_SHUTDOWN_SIGNAL), "SIG" ngx_value(NGX_SHUTDOWN_SIGNAL), - ", shutdowning", ngx_signal_handler }, { ngx_signal_value(NGX_CHANGEBIN_SIGNAL), "SIG" ngx_value(NGX_CHANGEBIN_SIGNAL), - ", changing binary", ngx_signal_handler }, - { SIGCHLD, "SIGCHLD", "", ngx_signal_handler }, + { SIGCHLD, "SIGCHLD", ngx_signal_handler }, - { SIGPIPE, "SIGPIPE, SIG_IGN", NULL, SIG_IGN }, + { SIGPIPE, "SIGPIPE, SIG_IGN", SIG_IGN }, - { 0, NULL, NULL, NULL } + { 0, NULL, NULL } }; @@ -98,6 +91,7 @@ int ngx_posix_init(ngx_log_t *log) void ngx_signal_handler(int signo) { + char *action; struct timeval tv; ngx_err_t err; ngx_signal_t *sig; @@ -113,37 +107,88 @@ void ngx_signal_handler(int signo) ngx_gettimeofday(&tv); ngx_time_update(tv.tv_sec); - ngx_log_error(NGX_LOG_INFO, ngx_cycle->log, 0, - "signal %d (%s) received%s", - signo, sig->signame, sig->action); + action = ""; + + switch (ngx_process) { + + case NGX_PROCESS_MASTER: + case NGX_PROCESS_QUITING: + case NGX_PROCESS_PAUSED: + switch (signo) { - switch (signo) { + case ngx_signal_value(NGX_SHUTDOWN_SIGNAL): + ngx_quit = 1; + action = ", shutdowning"; + break; + + case ngx_signal_value(NGX_TERMINATE_SIGNAL): + ngx_terminate = 1; + action = ", exiting"; + break; - case SIGCHLD: - ngx_reap = 1; - ngx_process_get_status(); - break; + case ngx_signal_value(NGX_PAUSE_SIGNAL): + ngx_pause = 1; + action = ", pausing"; + break; + + case ngx_signal_value(NGX_RECONFIGURE_SIGNAL): + ngx_reconfigure = 1; + action = ", reconfiguring"; + break; - case ngx_signal_value(NGX_SHUTDOWN_SIGNAL): - ngx_quit = 1; + case ngx_signal_value(NGX_REOPEN_SIGNAL): + ngx_reopen = 1; + action = ", reopen logs"; + break; + + case ngx_signal_value(NGX_CHANGEBIN_SIGNAL): + ngx_change_binary = 1; + action = ", changing binary"; + break; + + case SIGCHLD: + ngx_reap = 1; + break; + } + break; - case ngx_signal_value(NGX_TERMINATE_SIGNAL): - case ngx_signal_value(NGX_INTERRUPT_SIGNAL): - ngx_terminate = 1; - break; + case NGX_PROCESS_WORKER: + switch (signo) { + + case ngx_signal_value(NGX_SHUTDOWN_SIGNAL): + ngx_quit = 1; + action = ", shutdowning"; + break; + + case ngx_signal_value(NGX_TERMINATE_SIGNAL): + ngx_terminate = 1; + action = ", exiting"; + break; - case ngx_signal_value(NGX_RECONFIGURE_SIGNAL): - ngx_reconfigure = 1; +#if 0 + case ngx_signal_value(NGX_REOPEN_SIGNAL): + ngx_reopen = 1; + action = ", reopen logs"; + break; +#endif + + case ngx_signal_value(NGX_RECONFIGURE_SIGNAL): + case ngx_signal_value(NGX_REOPEN_SIGNAL): + case ngx_signal_value(NGX_PAUSE_SIGNAL): + case ngx_signal_value(NGX_CHANGEBIN_SIGNAL): + action = ", ignoring"; + break; + } + break; + } - case ngx_signal_value(NGX_REOPEN_SIGNAL): - ngx_reopen = 1; - break; + ngx_log_error(NGX_LOG_INFO, ngx_cycle->log, 0, + "signal %d (%s) received%s", signo, sig->signame, action); - case ngx_signal_value(NGX_CHANGEBIN_SIGNAL): - ngx_change_binary = 1; - break; + if (signo == SIGCHLD) { + ngx_process_get_status(); } ngx_set_errno(err); diff --git a/src/os/unix/ngx_process.c b/src/os/unix/ngx_process.c --- a/src/os/unix/ngx_process.c +++ b/src/os/unix/ngx_process.c @@ -112,7 +112,7 @@ static void ngx_exec_proc(ngx_cycle_t *c } -void ngx_signal_processes(ngx_cycle_t *cycle, ngx_int_t signal) +void ngx_signal_processes(ngx_cycle_t *cycle, ngx_int_t signo) { ngx_uint_t i; @@ -122,24 +122,26 @@ void ngx_signal_processes(ngx_cycle_t *c continue; } +#if 0 if (ngx_processes[i].exited) { if (i != --ngx_last_process) { ngx_processes[i--] = ngx_processes[ngx_last_process]; } continue; } +#endif ngx_log_debug2(NGX_LOG_DEBUG_CORE, cycle->log, 0, "kill (" PID_T_FMT ", %d)" , - ngx_processes[i].pid, signal); + ngx_processes[i].pid, signo); - if (kill(ngx_processes[i].pid, signal) == -1) { + if (kill(ngx_processes[i].pid, signo) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - "kill(%d, %d) failed", ngx_processes[i].pid, signal); + "kill(%d, %d) failed", ngx_processes[i].pid, signo); continue; } - if (signal != ngx_signal_value(NGX_REOPEN_SIGNAL)) { + if (signo != ngx_signal_value(NGX_REOPEN_SIGNAL)) { ngx_processes[i].exiting = 1; } } @@ -151,7 +153,7 @@ void ngx_respawn_processes(ngx_cycle_t * ngx_uint_t i; for (i = 0; i < ngx_last_process; i++) { - if (!ngx_processes[i].exited) { + if (ngx_processes[i].exiting || !ngx_processes[i].exited) { continue; } @@ -212,11 +214,7 @@ void ngx_process_get_status() for (i = 0; i < ngx_last_process; i++) { if (ngx_processes[i].pid == pid) { ngx_processes[i].status = status; - - if (!ngx_processes[i].exiting) { - ngx_processes[i].exited = 1; - } - + ngx_processes[i].exited = 1; process = ngx_processes[i].name; break; } diff --git a/src/os/unix/ngx_process.h b/src/os/unix/ngx_process.h --- a/src/os/unix/ngx_process.h +++ b/src/os/unix/ngx_process.h @@ -29,10 +29,11 @@ typedef struct { } ngx_exec_ctx_t; -#define NGX_PROCESS_SINGLE 0 -#define NGX_PROCESS_MASTER 1 -#define NGX_PROCESS_WORKER 2 -#define NGX_PROCESS_MASTER_QUIT 3 +#define NGX_PROCESS_SINGLE 0 +#define NGX_PROCESS_MASTER 1 +#define NGX_PROCESS_WORKER 2 +#define NGX_PROCESS_QUITING 3 +#define NGX_PROCESS_PAUSED 4 #define NGX_MAX_PROCESSES 1024 @@ -47,7 +48,7 @@ ngx_int_t ngx_spawn_process(ngx_cycle_t ngx_spawn_proc_pt proc, void *data, char *name, ngx_int_t respawn); ngx_int_t ngx_exec(ngx_cycle_t *cycle, ngx_exec_ctx_t *ctx); -void ngx_signal_processes(ngx_cycle_t *cycle, ngx_int_t signal); +void ngx_signal_processes(ngx_cycle_t *cycle, ngx_int_t signo); void ngx_respawn_processes(ngx_cycle_t *cycle); void ngx_process_get_status(void);