Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nginx/nginx.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src/os/unix
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2004-06-23 09:54:27 +0400
committerIgor Sysoev <igor@sysoev.ru>2004-06-23 09:54:27 +0400
commita1796d747c556e0dc8114e4e39aca6e57a8285f9 (patch)
treef7c020bf3f6b5713143d1732a17e0190659ebc34 /src/os/unix
parent3d5c0fc89e6a5e572e9e3071bd632cbc41b1f8d0 (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.c82
-rw-r--r--src/os/unix/ngx_process.h2
-rw-r--r--src/os/unix/ngx_process_cycle.c177
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;
}
}