# HG changeset patch # User Igor Sysoev # Date 1087970067 0 # Node ID fd24ba70e1b36ac2ea7c95930460f73a5819b407 # Parent 7c54d93f59658c0568ca2bc34173ae9c48ba011c nginx-0.0.7-2004-06-23-09:54:27 import diff --git a/auto/sources b/auto/sources --- a/auto/sources +++ b/auto/sources @@ -235,7 +235,7 @@ HTPP_FILE_CACHE_SRCS=src/http/ngx_http_f HTTP_CHARSET_FILTER_MODULE=ngx_http_charset_filter_module -HTTP_CHARSET_FILTER_SRCS=src/http/modules/ngx_http_charset_filter.c +HTTP_CHARSET_SRCS=src/http/modules/ngx_http_charset_filter.c HTTP_REWRITE_MODULE=ngx_http_rewrite_module diff --git a/src/core/ngx_core.h b/src/core/ngx_core.h --- a/src/core/ngx_core.h +++ b/src/core/ngx_core.h @@ -19,6 +19,7 @@ typedef struct ngx_connection_s ngx_con #include #include #include +#include #include #include #include @@ -31,7 +32,6 @@ typedef struct ngx_connection_s ngx_con #include #include #include -#include #include #include #include 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 @@ -23,40 +23,55 @@ ngx_pid_t ngx_spawn_process(ngx_cycle_t s = respawn >= 0 ? respawn : ngx_last_process; - /* Solaris 9 still has no AF_LOCAL */ + if (respawn != NGX_PROCESS_DETACHED) { + + /* Solaris 9 still has no AF_LOCAL */ + + if (socketpair(AF_UNIX, SOCK_STREAM, 0, ngx_processes[s].channel) == -1) + { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, + "socketpair() failed while spawning \"%s\"", name); + return NGX_ERROR; + } + + if (ngx_nonblocking(ngx_processes[s].channel[0]) == -1) { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, + ngx_nonblocking_n " failed while spawning \"%s\"", + name); + ngx_close_channel(ngx_processes[s].channel, cycle->log); + return NGX_ERROR; + } - if (socketpair(AF_UNIX, SOCK_STREAM, 0, ngx_processes[s].channel) == -1) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - "socketpair() failed while spawning \"%s\"", name); - return NGX_ERROR; - } + if (ngx_nonblocking(ngx_processes[s].channel[1]) == -1) { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, + ngx_nonblocking_n " failed while spawning \"%s\"", + name); + ngx_close_channel(ngx_processes[s].channel, cycle->log); + return NGX_ERROR; + } - if (ngx_nonblocking(ngx_processes[s].channel[0]) == -1) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - ngx_nonblocking_n " failed while spawning \"%s\"", name); - return NGX_ERROR; + on = 1; + if (ioctl(ngx_processes[s].channel[0], FIOASYNC, &on) == -1) { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, + "ioctl(FIOASYNC) failed while spawning \"%s\"", name); + ngx_close_channel(ngx_processes[s].channel, cycle->log); + return NGX_ERROR; + } + + if (fcntl(ngx_processes[s].channel[0], F_SETOWN, ngx_pid) == -1) { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, + "fcntl(F_SETOWN) failed while spawning \"%s\"", name); + ngx_close_channel(ngx_processes[s].channel, cycle->log); + return NGX_ERROR; + } + + ngx_channel = ngx_processes[s].channel[1]; + + } else { + ngx_processes[s].channel[0] = -1; + ngx_processes[s].channel[1] = -1; } - if (ngx_nonblocking(ngx_processes[s].channel[1]) == -1) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - ngx_nonblocking_n " failed while spawning \"%s\"", name); - return NGX_ERROR; - } - - on = 1; - if (ioctl(ngx_processes[s].channel[0], FIOASYNC, &on) == -1) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - "ioctl(FIOASYNC) failed while spawning \"%s\"", name); - return NGX_ERROR; - } - - if (fcntl(ngx_processes[s].channel[0], F_SETOWN, ngx_pid) == -1) { - ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, - "fcntl(F_SETOWN) failed while spawning \"%s\"", name); - return NGX_ERROR; - } - - ngx_channel = ngx_processes[s].channel[1]; ngx_process_slot = s; @@ -67,6 +82,7 @@ ngx_pid_t ngx_spawn_process(ngx_cycle_t case -1: ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "fork() failed while spawning \"%s\"", name); + ngx_close_channel(ngx_processes[s].channel, cycle->log); return NGX_ERROR; case 0: @@ -224,3 +240,15 @@ void ngx_process_get_status() } } } + + +void ngx_close_channel(ngx_fd_t *fd, ngx_log_t *log) +{ + if (close(fd[0]) == -1) { + ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "close() failed"); + } + + if (close(fd[1]) == -1) { + ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "close() failed"); + } +} 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 @@ -47,6 +47,8 @@ ngx_pid_t ngx_spawn_process(ngx_cycle_t char *name, ngx_int_t respawn); ngx_pid_t ngx_execute(ngx_cycle_t *cycle, ngx_exec_ctx_t *ctx); void ngx_process_get_status(void); +void ngx_close_channel(ngx_fd_t *fd, ngx_log_t *log); + extern ngx_pid_t ngx_pid; extern ngx_socket_t ngx_channel; diff --git a/src/os/unix/ngx_process_cycle.c b/src/os/unix/ngx_process_cycle.c --- a/src/os/unix/ngx_process_cycle.c +++ b/src/os/unix/ngx_process_cycle.c @@ -9,6 +9,7 @@ static void ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n, ngx_int_t type); static void ngx_signal_worker_processes(ngx_cycle_t *cycle, int signo); +static ngx_uint_t ngx_reap_childs(ngx_cycle_t *cycle); static void ngx_master_exit(ngx_cycle_t *cycle, ngx_master_ctx_t *ctx); static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data); static void ngx_channel_handler(ngx_event_t *ev); @@ -47,7 +48,7 @@ void ngx_master_process_cycle(ngx_cycle_ char *title; u_char *p; size_t size; - ngx_int_t n, i; + ngx_int_t i; sigset_t set; struct timeval tv; struct itimerval itv; @@ -77,16 +78,16 @@ void ngx_master_process_cycle(ngx_cycle_ size = sizeof(master_process); - for (n = 0; n < ctx->argc; n++) { - size += ngx_strlen(ctx->argv[n]) + 1; + for (i = 0; i < ctx->argc; i++) { + size += ngx_strlen(ctx->argv[i]) + 1; } title = ngx_palloc(cycle->pool, size); p = ngx_cpymem(title, master_process, sizeof(master_process) - 1); - for (n = 0; n < ctx->argc; n++) { + for (i = 0; i < ctx->argc; i++) { *p++ = ' '; - p = ngx_cpystrn(p, (u_char *) ctx->argv[n], size); + p = ngx_cpystrn(p, (u_char *) ctx->argv[i], size); } ngx_setproctitle(title); @@ -132,59 +133,7 @@ void ngx_master_process_cycle(ngx_cycle_ ngx_reap = 0; ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "reap childs"); - live = 0; - for (i = 0; i < ngx_last_process; i++) { - - ngx_log_debug6(NGX_LOG_DEBUG_EVENT, cycle->log, 0, - "child: " PID_T_FMT " e:%d t:%d d:%d r:%d j:%d", - ngx_processes[i].pid, - ngx_processes[i].exiting, - ngx_processes[i].exited, - ngx_processes[i].detached, - ngx_processes[i].respawn, - ngx_processes[i].just_respawn); - - if (ngx_processes[i].exited) { - - if (ngx_processes[i].respawn - && !ngx_processes[i].exiting - && !ngx_terminate - && !ngx_quit) - { - 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); - continue; - } - - live = 1; - - continue; - } - - if (ngx_processes[i].pid == ngx_new_binary) { - ngx_new_binary = 0; - if (ngx_noaccepting) { - ngx_restart = 1; - ngx_noaccepting = 0; - } - } - - if (i != --ngx_last_process) { - ngx_processes[i--] = ngx_processes[ngx_last_process]; - } - - } else if (ngx_processes[i].exiting - || !ngx_processes[i].detached) - { - live = 1; - } - } + live = ngx_reap_childs(cycle); } if (!live && (ngx_terminate || ngx_quit)) { @@ -352,9 +301,9 @@ static void ngx_start_worker_processes(n for (i = 0; i < ngx_last_process - 1; i++) { - ngx_log_debug3(NGX_LOG_DEBUG_CORE, cycle->log, 0, - "pass channel s: %d pid:" PID_T_FMT " fd:%d", - ch.slot, ch.pid, ch.fd); + ngx_log_debug4(NGX_LOG_DEBUG_CORE, cycle->log, 0, + "pass channel s: %d pid:" PID_T_FMT " fd:%d to:" + PID_T_FMT, ch.slot, ch.pid, ch.fd, ngx_processes[i].pid); /* TODO: NGX_AGAIN */ @@ -464,6 +413,97 @@ static void ngx_signal_worker_processes( } +static ngx_uint_t ngx_reap_childs(ngx_cycle_t *cycle) +{ + ngx_int_t i, n; + ngx_uint_t live; + ngx_channel_t ch; + + ch.command = NGX_CMD_CLOSE_CHANNEL; + ch.fd = -1; + + live = 0; + for (i = 0; i < ngx_last_process; i++) { + + ngx_log_debug6(NGX_LOG_DEBUG_EVENT, cycle->log, 0, + "child: " PID_T_FMT " e:%d t:%d d:%d r:%d j:%d", + ngx_processes[i].pid, + ngx_processes[i].exiting, + ngx_processes[i].exited, + ngx_processes[i].detached, + ngx_processes[i].respawn, + ngx_processes[i].just_respawn); + + if (ngx_processes[i].exited) { + + if (!ngx_processes[i].detached) { + ngx_close_channel(ngx_processes[i].channel, cycle->log); + + ngx_processes[i].channel[0] = -1; + ngx_processes[i].channel[1] = -1; + + ch.pid = ngx_processes[i].pid; + ch.slot = i; + + for (n = 0; n < ngx_last_process; n++) { + if (ngx_processes[n].exited + || ngx_processes[n].channel[0] == -1) + { + continue; + } + + ngx_log_debug3(NGX_LOG_DEBUG_CORE, cycle->log, 0, + "pass close channel s: %d pid:" PID_T_FMT + " to:" PID_T_FMT, ch.slot, ch.pid, ngx_processes[n].pid); + + /* TODO: NGX_AGAIN */ + + ngx_write_channel(ngx_processes[n].channel[0], + &ch, sizeof(ngx_channel_t), cycle->log); + } + } + + if (ngx_processes[i].respawn + && !ngx_processes[i].exiting + && !ngx_terminate + && !ngx_quit) + { + 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); + continue; + } + + live = 1; + + continue; + } + + if (ngx_processes[i].pid == ngx_new_binary) { + ngx_new_binary = 0; + if (ngx_noaccepting) { + ngx_restart = 1; + ngx_noaccepting = 0; + } + } + + if (i != --ngx_last_process) { + ngx_processes[i--] = ngx_processes[ngx_last_process]; + } + + } else if (ngx_processes[i].exiting || !ngx_processes[i].detached) { + live = 1; + } + } + + return live; +} + + static void ngx_master_exit(ngx_cycle_t *cycle, ngx_master_ctx_t *ctx) { ngx_delete_pidfile(cycle); @@ -712,6 +752,21 @@ static void ngx_channel_handler(ngx_even ngx_processes[ch.slot].pid = ch.pid; ngx_processes[ch.slot].channel[0] = ch.fd; break; + + case NGX_CMD_CLOSE_CHANNEL: + + ngx_log_debug4(NGX_LOG_DEBUG_CORE, ev->log, 0, + "close channel s:%d pid:" PID_T_FMT " our:" PID_T_FMT + " fd:%d", + ch.slot, ch.pid, ngx_processes[ch.slot].pid, + ngx_processes[ch.slot].channel[0]); + + if (close(ngx_processes[ch.slot].channel[0]) == -1) { + ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_errno, "close() failed"); + } + + ngx_processes[ch.slot].channel[0] = -1; + break; } }