changeset 365:fd24ba70e1b3

nginx-0.0.7-2004-06-23-09:54:27 import
author Igor Sysoev <igor@sysoev.ru>
date Wed, 23 Jun 2004 05:54:27 +0000
parents 7c54d93f5965
children e411b1482ee3
files auto/sources src/core/ngx_core.h src/os/unix/ngx_process.c src/os/unix/ngx_process.h src/os/unix/ngx_process_cycle.c
diffstat 5 files changed, 178 insertions(+), 93 deletions(-) [+]
line wrap: on
line diff
--- 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
--- a/src/core/ngx_core.h
+++ b/src/core/ngx_core.h
@@ -19,6 +19,7 @@ typedef struct ngx_connection_s  ngx_con
 #include <ngx_time.h>
 #include <ngx_socket.h>
 #include <ngx_errno.h>
+#include <ngx_types.h>
 #include <ngx_shared.h>
 #include <ngx_process.h>
 #include <ngx_thread.h>
@@ -31,7 +32,6 @@ typedef struct ngx_connection_s  ngx_con
 #include <ngx_buf.h>
 #include <ngx_array.h>
 #include <ngx_table.h>
-#include <ngx_types.h>
 #include <ngx_file.h>
 #include <ngx_files.h>
 #include <ngx_crc.h>
--- 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");
+    } 
+}
--- 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;
--- 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;
     }
 }