changeset 221:401154e21826

nginx-0.0.1-2004-01-08-20:08:10 import
author Igor Sysoev <igor@sysoev.ru>
date Thu, 08 Jan 2004 17:08:10 +0000
parents 4f81b931e9ff
children 99df0edb63ed
files src/core/nginx.c src/os/unix/ngx_os.h src/os/unix/ngx_posix_init.c src/os/unix/ngx_process.c src/os/unix/ngx_process.h
diffstat 5 files changed, 112 insertions(+), 115 deletions(-) [+]
line wrap: on
line diff
--- a/src/core/nginx.c
+++ b/src/core/nginx.c
@@ -5,21 +5,27 @@
 #include <nginx.h>
 
 
-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;
 
--- 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;
--- 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;
 
--- 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;
--- 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];