# HG changeset patch # User Igor Sysoev # Date 1073581690 0 # Node ID 401154e2182670668c8b16526f2e31230ab46623 # Parent 4f81b931e9ff7bf500a16ebfdcebed293a83629b nginx-0.0.1-2004-01-08-20:08:10 import diff --git a/src/core/nginx.c b/src/core/nginx.c --- a/src/core/nginx.c +++ b/src/core/nginx.c @@ -5,21 +5,27 @@ #include -static void ngx_master_process_cycle(ngx_cycle_t *cycle); +typedef struct { + ngx_str_t user; + int daemon; + int master; + ngx_str_t pid; +} ngx_core_conf_t; + + +typedef struct { + ngx_file_t pid; + char *const *argv; +} ngx_master_ctx_t; + + +static void ngx_master_process_cycle(ngx_cycle_t *cycle, ngx_master_ctx_t *ctx); static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data); static ngx_int_t ngx_add_inherited_sockets(ngx_cycle_t *cycle, char **envp); static void ngx_exec_new_binary(ngx_cycle_t *cycle, char *const *argv); static ngx_int_t ngx_core_module_init(ngx_cycle_t *cycle); -typedef struct { - ngx_str_t user; - int daemon; - int single; - ngx_str_t pid; -} ngx_core_conf_t; - - static ngx_str_t core_name = ngx_string("core"); static ngx_command_t ngx_core_commands[] = { @@ -38,11 +44,11 @@ static ngx_command_t ngx_core_commands[ offsetof(ngx_core_conf_t, daemon), NULL }, - { ngx_string("single_process"), + { ngx_string("master_process"), NGX_MAIN_CONF|NGX_CONF_TAKE1, ngx_conf_set_core_flag_slot, 0, - offsetof(ngx_core_conf_t, single), + offsetof(ngx_core_conf_t, master), NULL }, ngx_null_command @@ -70,7 +76,7 @@ u_int ngx_connection_counter; ngx_int_t ngx_process; -ngx_int_t ngx_respawn; +ngx_int_t ngx_reap; ngx_int_t ngx_terminate; ngx_int_t ngx_quit; ngx_int_t ngx_reconfigure; @@ -86,10 +92,10 @@ int main(int argc, char *const *argv, ch ngx_cycle_t *cycle, init_cycle; ngx_open_file_t *file; ngx_core_conf_t *ccf; + ngx_master_ctx_t ctx; #if !(WIN32) size_t len; char pid[/* STUB */ 10]; - ngx_file_t pidfile; struct passwd *pwd; #endif @@ -100,6 +106,7 @@ int main(int argc, char *const *argv, ch /* TODO */ ngx_max_sockets = -1; ngx_time_init(); + #if (HAVE_PCRE) ngx_regex_init(); #endif @@ -138,7 +145,7 @@ int main(int argc, char *const *argv, ch ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); - ngx_process = (ccf->single == 1) ? NGX_PROCESS_SINGLE : NGX_PROCESS_MASTER; + ngx_process = (ccf->master != 0) ? NGX_PROCESS_MASTER : NGX_PROCESS_SINGLE; #if (WIN32) @@ -187,40 +194,61 @@ int main(int argc, char *const *argv, ch } len = ngx_snprintf(pid, /* STUB */ 10, PID_T_FMT, ngx_getpid()); - ngx_memzero(&pidfile, sizeof(ngx_file_t)); - pidfile.name = ccf->pid; + ngx_memzero(&ctx.pid, sizeof(ngx_file_t)); + ctx.pid.name = ccf->pid; - pidfile.fd = ngx_open_file(pidfile.name.data, NGX_FILE_RDWR, + ctx.pid.fd = ngx_open_file(ctx.pid.name.data, NGX_FILE_RDWR, NGX_FILE_CREATE_OR_OPEN); - if (pidfile.fd == NGX_INVALID_FILE) { + if (ctx.pid.fd == NGX_INVALID_FILE) { ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, - ngx_open_file_n " \"%s\" failed", pidfile.name.data); + ngx_open_file_n " \"%s\" failed", ctx.pid.name.data); return 1; } - if (ngx_write_file(&pidfile, pid, len, 0) == NGX_ERROR) { + if (ngx_write_file(&ctx.pid, pid, len, 0) == NGX_ERROR) { return 1; } - if (ngx_close_file(pidfile.fd) == NGX_FILE_ERROR) { + if (ngx_close_file(ctx.pid.fd) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - ngx_close_file_n " \"%s\" failed", pidfile.name.data); + ngx_close_file_n " \"%s\" failed", ctx.pid.name.data); } #endif - ngx_master_process_cycle(cycle); + ctx.argv = argv; + + ngx_master_process_cycle(cycle, &ctx); return 0; } -static void ngx_master_process_cycle(ngx_cycle_t *cycle) +static void ngx_master_process_cycle(ngx_cycle_t *cycle, ngx_master_ctx_t *ctx) { + ngx_msec_t delay; struct timeval tv; ngx_int_t i; - ngx_err_t err; + sigset_t set, wset; + + delay = 1000; + + sigemptyset(&set); + 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_TERMINATE_SIGNAL)); + sigaddset(&set, ngx_signal_value(NGX_SHUTDOWN_SIGNAL)); + sigaddset(&set, ngx_signal_value(NGX_CHANGEBIN_SIGNAL)); + + sigemptyset(&wset); + + if (sigprocmask(SIG_BLOCK, &set, NULL) == -1) { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, + "sigprocmask() failed"); + } for ( ;; ) { ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "new cycle"); @@ -242,7 +270,6 @@ static void ngx_master_process_cycle(ngx } } - /* a cycle with the same configuration */ for ( ;; ) { @@ -251,38 +278,48 @@ static void ngx_master_process_cycle(ngx for ( ;; ) { - err = 0; + if (ngx_process == NGX_PROCESS_MASTER) { + sigsuspend(&wset); - if (ngx_process == NGX_PROCESS_SINGLE) { + ngx_gettimeofday(&tv); + ngx_time_update(tv.tv_sec); + + } else if (ngx_process == NGX_PROCESS_SINGLE) { ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "worker cycle"); ngx_process_events(cycle->log); - } else { - ngx_set_errno(0); - ngx_msleep(1000); - err = ngx_errno; + } else if (ngx_process == NGX_PROCESS_MASTER_QUIT) { + if (delay < 10000) { + delay *= 2; + } + + if (sigprocmask(SIG_UNBLOCK, &set, NULL) == -1) { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, + "sigprocmask() failed"); + continue; + } + + ngx_msleep(delay); ngx_gettimeofday(&tv); ngx_time_update(tv.tv_sec); - if (err) { - ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, err, - "sleep() exited"); + if (sigprocmask(SIG_BLOCK, &set, NULL) == -1) { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, + "sigprocmask() failed"); } } if (ngx_quit || ngx_terminate) { #if !(WIN32) -#if 0 - if (ngx_delete_file(pidfile.name.data) == NGX_FILE_ERROR) { + 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", - pidfile.name.data); + ctx->pid.name.data); } #endif -#endif ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "exiting"); @@ -302,19 +339,19 @@ static void ngx_master_process_cycle(ngx exit(0); } - if (err == NGX_EINTR) { + if (ngx_reap) { + ngx_reap = 0; ngx_respawn_processes(cycle); } -#if 0 if (ngx_change_binary) { ngx_change_binary = 0; ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "changing binary"); - ngx_exec_new_binary(cycle, argv); + ngx_exec_new_binary(cycle, ctx->argv); + /* TODO: quit workers */ } -#endif if (ngx_reconfigure) { ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "reconfiguring"); @@ -346,6 +383,7 @@ static void ngx_master_process_cycle(ngx static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data) { + sigset_t set; ngx_int_t i; ngx_listening_t *ls; @@ -360,6 +398,13 @@ static void ngx_worker_process_cycle(ngx } } + sigemptyset(&set); + + if (sigprocmask(SIG_SETMASK, &set, NULL) == -1) { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, + "sigprocmask() failed"); + } + ngx_init_temp_number(); /* @@ -518,7 +563,7 @@ static ngx_int_t ngx_core_module_init(ng * ccf->pid = NULL; */ ccf->daemon = -1; - ccf->single = -1; + ccf->master = -1; ((void **)(cycle->conf_ctx))[ngx_core_module.index] = ccf; 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 @@ -49,8 +49,9 @@ extern int ngx_max_sockets; extern int ngx_inherited_nonblocking; -extern ngx_int_t ngx_master; +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_reconfigure; 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 @@ -120,6 +120,7 @@ void ngx_signal_handler(int signo) switch (signo) { case SIGCHLD: + ngx_reap = 1; ngx_process_get_status(); break; 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 @@ -8,14 +8,6 @@ static void ngx_exec_proc(ngx_cycle_t *c ngx_uint_t ngx_last_process; ngx_process_t ngx_processes[NGX_MAX_PROCESSES]; -sigset_t ngx_sigmask; - - -void ngx_wait_events() -{ - sigsuspend(&ngx_sigmask); -} - ngx_int_t ngx_spawn_process(ngx_cycle_t *cycle, ngx_spawn_proc_pt proc, void *data, @@ -122,17 +114,8 @@ static void ngx_exec_proc(ngx_cycle_t *c void ngx_signal_processes(ngx_cycle_t *cycle, ngx_int_t signal) { - sigset_t set, oset; ngx_uint_t i; - sigemptyset(&set); - sigaddset(&set, SIGCHLD); - if (sigprocmask(SIG_BLOCK, &set, &oset) == -1) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - "sigprocmask() failed while signaling processes"); - return; - } - for (i = 0; i < ngx_last_process; i++) { if (ngx_processes[i].detached) { @@ -160,61 +143,32 @@ void ngx_signal_processes(ngx_cycle_t *c ngx_processes[i].exiting = 1; } } - - if (sigprocmask(SIG_SETMASK, &oset, &set) == -1) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - "sigprocmask() failed while signaling processes"); - } } void ngx_respawn_processes(ngx_cycle_t *cycle) { - sigset_t set, oset; ngx_uint_t i; - sigemptyset(&set); - sigaddset(&set, SIGCHLD); - if (sigprocmask(SIG_BLOCK, &set, &oset) == -1) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - "sigprocmask() failed while respawning processes"); - return; - } - - /* - * to avoid a race condition we can check and set value of ngx_respawn - * only in signal handler or while SIGCHLD is blocked - */ - - if (ngx_respawn) { - - for (i = 0; i < ngx_last_process; i++) { - if (!ngx_processes[i].exited) { - continue; - } - - if (!ngx_processes[i].respawn) { - if (i != --ngx_last_process) { - ngx_processes[i--] = ngx_processes[ngx_last_process]; - } - continue; - } - - if (ngx_spawn_process(cycle, - ngx_processes[i].proc, ngx_processes[i].data, - ngx_processes[i].name, i) == NGX_ERROR) - { - ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, - "can not respawn %s", ngx_processes[i].name); - } + for (i = 0; i < ngx_last_process; i++) { + if (!ngx_processes[i].exited) { + continue; } - ngx_respawn = 0; - } + if (!ngx_processes[i].respawn) { + if (i != --ngx_last_process) { + ngx_processes[i--] = ngx_processes[ngx_last_process]; + } + continue; + } - if (sigprocmask(SIG_SETMASK, &oset, &set) == -1) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - "sigprocmask() failed while respawning processes"); + if (ngx_spawn_process(cycle, + ngx_processes[i].proc, ngx_processes[i].data, + ngx_processes[i].name, i) == NGX_ERROR) + { + ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, + "can not respawn %s", ngx_processes[i].name); + } } } @@ -261,10 +215,6 @@ void ngx_process_get_status() if (!ngx_processes[i].exiting) { ngx_processes[i].exited = 1; - - if (ngx_processes[i].respawn) { - ngx_respawn = 1; - } } process = ngx_processes[i].name; 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,9 +29,10 @@ typedef struct { } ngx_exec_ctx_t; -#define NGX_PROCESS_SINGLE 0 -#define NGX_PROCESS_MASTER 1 -#define NGX_PROCESS_WORKER 2 +#define NGX_PROCESS_SINGLE 0 +#define NGX_PROCESS_MASTER 1 +#define NGX_PROCESS_WORKER 2 +#define NGX_PROCESS_MASTER_QUIT 3 #define NGX_MAX_PROCESSES 1024 @@ -50,7 +51,6 @@ void ngx_signal_processes(ngx_cycle_t *c void ngx_respawn_processes(ngx_cycle_t *cycle); void ngx_process_get_status(void); -extern ngx_int_t ngx_respawn; extern ngx_uint_t ngx_last_process; extern ngx_process_t ngx_processes[NGX_MAX_PROCESSES];