diff options
author | Igor Sysoev <igor@sysoev.ru> | 2004-06-23 09:54:27 +0400 |
---|---|---|
committer | Igor Sysoev <igor@sysoev.ru> | 2004-06-23 09:54:27 +0400 |
commit | a1796d747c556e0dc8114e4e39aca6e57a8285f9 (patch) | |
tree | f7c020bf3f6b5713143d1732a17e0190659ebc34 /src/os/unix | |
parent | 3d5c0fc89e6a5e572e9e3071bd632cbc41b1f8d0 (diff) |
nginx-0.0.7-2004-06-23-09:54:27 import
Diffstat (limited to 'src/os/unix')
-rw-r--r-- | src/os/unix/ngx_process.c | 82 | ||||
-rw-r--r-- | src/os/unix/ngx_process.h | 2 | ||||
-rw-r--r-- | src/os/unix/ngx_process_cycle.c | 177 |
3 files changed, 173 insertions, 88 deletions
diff --git a/src/os/unix/ngx_process.c b/src/os/unix/ngx_process.c index d2c1e30a5..799eabee3 100644 --- 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 *cycle, s = respawn >= 0 ? respawn : ngx_last_process; - /* Solaris 9 still has no AF_LOCAL */ + if (respawn != NGX_PROCESS_DETACHED) { - 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; - } + /* Solaris 9 still has no AF_LOCAL */ - 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; - } + 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); - 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; + } - 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 (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 (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; + 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; } - ngx_channel = ngx_processes[s].channel[1]; ngx_process_slot = s; @@ -67,6 +82,7 @@ ngx_pid_t ngx_spawn_process(ngx_cycle_t *cycle, 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 index 99374ebb1..ccea40db7 100644 --- 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 *cycle, 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 index fec4210d7..547f88ca1 100644 --- 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_t *cycle, ngx_master_ctx_t *ctx) 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_t *cycle, ngx_master_ctx_t *ctx) 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_t *cycle, ngx_master_ctx_t *ctx) 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(ngx_cycle_t *cycle, ngx_int_t 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(ngx_cycle_t *cycle, int signo) } +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_event_t *ev) 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; } } |