changeset 222:99df0edb63ed

nginx-0.0.1-2004-01-09-00:02:06 import
author Igor Sysoev <igor@sysoev.ru>
date Thu, 08 Jan 2004 21:02:06 +0000
parents 401154e21826
children 5d168ebc1ecc
files src/core/nginx.c src/core/nginx.h src/core/ngx_config.h 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 7 files changed, 186 insertions(+), 91 deletions(-) [+]
line wrap: on
line diff
--- a/src/core/nginx.c
+++ b/src/core/nginx.c
@@ -10,6 +10,7 @@ typedef struct {
      int        daemon;
      int        master;
      ngx_str_t  pid;
+     ngx_str_t  newpid;
 } ngx_core_conf_t;
 
 
@@ -74,11 +75,11 @@ uid_t      user;
 u_int ngx_connection_counter;
 
 ngx_int_t  ngx_process;
-
-
+ngx_int_t  ngx_inherited;
 ngx_int_t  ngx_reap;
 ngx_int_t  ngx_terminate;
 ngx_int_t  ngx_quit;
+ngx_int_t  ngx_pause;
 ngx_int_t  ngx_reconfigure;
 ngx_int_t  ngx_reopen;
 ngx_int_t  ngx_change_binary;
@@ -191,11 +192,13 @@ int main(int argc, char *const *argv, ch
     if (ccf->pid.len == 0) {
         ccf->pid.len = sizeof(NGINX_PID) - 1;
         ccf->pid.data = NGINX_PID;
+        ccf->newpid.len = sizeof(NGINX_NEW_PID) - 1;
+        ccf->newpid.data = NGINX_NEW_PID;
     }
 
     len = ngx_snprintf(pid, /* STUB */ 10, PID_T_FMT, ngx_getpid());
     ngx_memzero(&ctx.pid, sizeof(ngx_file_t));
-    ctx.pid.name = ccf->pid;
+    ctx.pid.name = ngx_inherited ? ccf->newpid : ccf->pid;
 
     ctx.pid.fd = ngx_open_file(ctx.pid.name.data, NGX_FILE_RDWR,
                                NGX_FILE_CREATE_OR_OPEN);
@@ -229,7 +232,7 @@ static void ngx_master_process_cycle(ngx
 {
     ngx_msec_t      delay;
     struct timeval  tv;
-    ngx_int_t       i;
+    ngx_uint_t      i, live;
     sigset_t        set, wset;
 
     delay = 1000;
@@ -238,7 +241,7 @@ static void ngx_master_process_cycle(ngx
     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_PAUSE_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));
@@ -290,7 +293,12 @@ static void ngx_master_process_cycle(ngx
 
                     ngx_process_events(cycle->log);
 
-                } else if (ngx_process == NGX_PROCESS_MASTER_QUIT) {
+                } else if (ngx_process == NGX_PROCESS_QUITING
+                           || ngx_process == NGX_PROCESS_PAUSED)
+                {
+                    ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
+                                   "quit cycle");
+
                     if (delay < 10000) {
                         delay *= 2;
                     }
@@ -301,42 +309,75 @@ static void ngx_master_process_cycle(ngx
                         continue;
                     }
 
-                    ngx_msleep(delay);
+                    if (ngx_reap == 0) {
+                        ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
+                                       "sleep %d", delay / 1000);
+
+                        ngx_msleep(delay);
 
-                    ngx_gettimeofday(&tv);
-                    ngx_time_update(tv.tv_sec);
+                        ngx_gettimeofday(&tv);
+                        ngx_time_update(tv.tv_sec);
+
+                        ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
+                                       "wake up");
+                    }
 
                     if (sigprocmask(SIG_BLOCK, &set, NULL) == -1) {
                         ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                                       "sigprocmask() failed");
                     }
+
+                    if (ngx_reap) {
+                        ngx_reap = 0;
+
+                        live = 0;
+                        for (i = 0; i < ngx_last_process; i++) {
+                            if (ngx_processes[i].exiting
+                                && !ngx_processes[i].exited)
+                            {
+                                live = 1;
+                                continue;
+                            }
+
+                            if (i != --ngx_last_process) {
+                                ngx_processes[i--] =
+                                               ngx_processes[ngx_last_process];
+                            }
+                        }
+
+                        if (live == 0 && ngx_process == NGX_PROCESS_QUITING) {
+                            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",
+                                              ctx->pid.name.data);
+                            }
+
+                            ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "exit");
+                            exit(0);
+                        }
+                    }
                 }
 
-                if (ngx_quit || ngx_terminate) {
-#if !(WIN32)
-                    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",
-                                      ctx->pid.name.data);
-                    }
-#endif
-
-                    ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "exiting");
+                if (ngx_terminate) {
+                    ngx_signal_processes(cycle,
+                                       ngx_signal_value(NGX_TERMINATE_SIGNAL));
+                    ngx_process = NGX_PROCESS_QUITING;
+                }
 
-                    if (ngx_process == NGX_PROCESS_MASTER) {
-                        ngx_signal_processes(cycle,
+                if (ngx_quit) {
+                    ngx_signal_processes(cycle,
                                         ngx_signal_value(NGX_SHUTDOWN_SIGNAL));
-
-                        /* TODO: wait workers */
+                    ngx_process = NGX_PROCESS_QUITING;
+                }
 
-                        ngx_msleep(1000);
-
-                        ngx_gettimeofday(&tv);
-                        ngx_time_update(tv.tv_sec);
-                    }
-
-                    ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "exit");
-                    exit(0);
+                if (ngx_pause || ngx_process != NGX_PROCESS_PAUSED) {
+                    ngx_signal_processes(cycle,
+                                        ngx_signal_value(NGX_SHUTDOWN_SIGNAL));
+                    ngx_process = NGX_PROCESS_PAUSED;
                 }
 
                 if (ngx_reap) {
@@ -349,8 +390,6 @@ static void ngx_master_process_cycle(ngx
                     ngx_log_error(NGX_LOG_INFO, cycle->log, 0,
                                   "changing binary");
                     ngx_exec_new_binary(cycle, ctx->argv);
-
-                    /* TODO: quit workers */
                 }
 
                 if (ngx_reconfigure) {
@@ -367,13 +406,20 @@ static void ngx_master_process_cycle(ngx
 
             }
 
-            cycle = ngx_init_cycle(cycle);
-            if (cycle == NULL) {
-                cycle = (ngx_cycle_t *) ngx_cycle;
-                continue;
+            if (ngx_pause) {
+                ngx_pause = 0;
+                ngx_process = NGX_PROCESS_MASTER;
+
+            } else {
+                cycle = ngx_init_cycle(cycle);
+                if (cycle == NULL) {
+                    cycle = (ngx_cycle_t *) ngx_cycle;
+                    continue;
+                }
+
+                ngx_cycle = cycle;
             }
 
-            ngx_cycle = cycle;
             ngx_reconfigure = 0;
             break;
         }
@@ -388,6 +434,7 @@ static void ngx_worker_process_cycle(ngx
     ngx_listening_t  *ls;
 
     ngx_process = NGX_PROCESS_WORKER;
+    ngx_last_process = 0;
 
     if (user) {
         if (setuid(user) == -1) {
@@ -502,6 +549,8 @@ static ngx_int_t ngx_add_inherited_socke
             }
         }
 
+        ngx_inherited = 1;
+
         return ngx_set_inherited_sockets(cycle);
     }
 
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -5,6 +5,7 @@
 #define NGINX_VER      "nginx/0.0.1"
 #define NGINX_CONF     "nginx.conf"
 #define NGINX_PID      "nginx.pid"
+#define NGINX_NEW_PID  NGINX_PID ".newbin"
 
 #define NGINX_VAR      "NGINX="
 #define NGINX_VAR_LEN  (sizeof(NGINX_VAR) - 1)
--- a/src/core/ngx_config.h
+++ b/src/core/ngx_config.h
@@ -63,11 +63,11 @@ typedef u_int  ngx_uint_t;
 #define ngx_signal_value(n)      ngx_signal_helper(n)
 
 /* TODO: #ifndef */
+#define NGX_SHUTDOWN_SIGNAL      QUIT
+#define NGX_TERMINATE_SIGNAL     TERM
+#define NGX_PAUSE_SIGNAL         INT
 #define NGX_RECONFIGURE_SIGNAL   HUP
 #define NGX_REOPEN_SIGNAL        USR1
-#define NGX_SHUTDOWN_SIGNAL      QUIT
-#define NGX_TERMINATE_SIGNAL     TERM
-#define NGX_INTERRUPT_SIGNAL     INT
 #define NGX_CHANGEBIN_SIGNAL     USR2
 
 #endif
--- a/src/os/unix/ngx_os.h
+++ b/src/os/unix/ngx_os.h
@@ -54,6 +54,7 @@ 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_pause;
 extern ngx_int_t    ngx_reconfigure;
 extern ngx_int_t    ngx_reopen;
 extern ngx_int_t    ngx_change_binary;
--- a/src/os/unix/ngx_posix_init.c
+++ b/src/os/unix/ngx_posix_init.c
@@ -13,7 +13,6 @@ void ngx_signal_handler(int signo);
 typedef struct {
      int     signo;
      char   *signame;
-     char   *action;
      void  (*handler)(int signo);
 } ngx_signal_t;
 
@@ -21,39 +20,33 @@ typedef struct {
 ngx_signal_t  signals[] = {
     { ngx_signal_value(NGX_RECONFIGURE_SIGNAL),
       "SIG" ngx_value(NGX_RECONFIGURE_SIGNAL),
-      ", reconfiguring",
       ngx_signal_handler },
 
     { ngx_signal_value(NGX_REOPEN_SIGNAL),
       "SIG" ngx_value(NGX_REOPEN_SIGNAL),
-      ", reopen logs",
       ngx_signal_handler },
 
-    { ngx_signal_value(NGX_INTERRUPT_SIGNAL),
-      "SIG" ngx_value(NGX_INTERRUPT_SIGNAL),
-      ", exiting",
+    { ngx_signal_value(NGX_PAUSE_SIGNAL),
+      "SIG" ngx_value(NGX_PAUSE_SIGNAL),
       ngx_signal_handler },
 
     { ngx_signal_value(NGX_TERMINATE_SIGNAL),
       "SIG" ngx_value(NGX_TERMINATE_SIGNAL),
-      ", exiting",
       ngx_signal_handler },
 
     { ngx_signal_value(NGX_SHUTDOWN_SIGNAL),
       "SIG" ngx_value(NGX_SHUTDOWN_SIGNAL),
-      ", shutdowning",
       ngx_signal_handler },
 
     { ngx_signal_value(NGX_CHANGEBIN_SIGNAL),
       "SIG" ngx_value(NGX_CHANGEBIN_SIGNAL),
-      ", changing binary",
       ngx_signal_handler },
 
-    { SIGCHLD, "SIGCHLD", "", ngx_signal_handler },
+    { SIGCHLD, "SIGCHLD", ngx_signal_handler },
 
-    { SIGPIPE, "SIGPIPE, SIG_IGN", NULL, SIG_IGN },
+    { SIGPIPE, "SIGPIPE, SIG_IGN", SIG_IGN },
 
-    { 0, NULL, NULL, NULL }
+    { 0, NULL, NULL }
 };
 
 
@@ -98,6 +91,7 @@ int ngx_posix_init(ngx_log_t *log)
 
 void ngx_signal_handler(int signo)
 {
+    char            *action;
     struct timeval   tv;
     ngx_err_t        err;
     ngx_signal_t    *sig;
@@ -113,37 +107,88 @@ void ngx_signal_handler(int signo)
     ngx_gettimeofday(&tv);
     ngx_time_update(tv.tv_sec);
 
-    ngx_log_error(NGX_LOG_INFO, ngx_cycle->log, 0,
-                  "signal %d (%s) received%s",
-                  signo, sig->signame, sig->action);
+    action = "";
+
+    switch (ngx_process) {
+
+    case NGX_PROCESS_MASTER:
+    case NGX_PROCESS_QUITING:
+    case NGX_PROCESS_PAUSED:
+        switch (signo) {
 
-    switch (signo) {
+        case ngx_signal_value(NGX_SHUTDOWN_SIGNAL):
+            ngx_quit = 1;
+            action = ", shutdowning";
+            break;
+
+        case ngx_signal_value(NGX_TERMINATE_SIGNAL):
+            ngx_terminate = 1;
+            action = ", exiting";
+            break;
 
-    case SIGCHLD:
-        ngx_reap = 1;
-        ngx_process_get_status();
-        break;
+        case ngx_signal_value(NGX_PAUSE_SIGNAL):
+            ngx_pause = 1;
+            action = ", pausing";
+            break;
+
+        case ngx_signal_value(NGX_RECONFIGURE_SIGNAL):
+            ngx_reconfigure = 1;
+            action = ", reconfiguring";
+            break;
 
-    case ngx_signal_value(NGX_SHUTDOWN_SIGNAL):
-        ngx_quit = 1;
+        case ngx_signal_value(NGX_REOPEN_SIGNAL):
+            ngx_reopen = 1;
+            action = ", reopen logs";
+            break;
+
+        case ngx_signal_value(NGX_CHANGEBIN_SIGNAL):
+            ngx_change_binary = 1;
+            action = ", changing binary";
+            break;
+
+        case SIGCHLD:
+            ngx_reap = 1;
+            break;
+        }
+
         break;
 
-    case ngx_signal_value(NGX_TERMINATE_SIGNAL):
-    case ngx_signal_value(NGX_INTERRUPT_SIGNAL):
-        ngx_terminate = 1;
-        break;
+    case NGX_PROCESS_WORKER:
+        switch (signo) {
+
+        case ngx_signal_value(NGX_SHUTDOWN_SIGNAL):
+            ngx_quit = 1;
+            action = ", shutdowning";
+            break;
+
+        case ngx_signal_value(NGX_TERMINATE_SIGNAL):
+            ngx_terminate = 1;
+            action = ", exiting";
+            break;
 
-    case ngx_signal_value(NGX_RECONFIGURE_SIGNAL):
-        ngx_reconfigure = 1;
+#if 0
+        case ngx_signal_value(NGX_REOPEN_SIGNAL):
+            ngx_reopen = 1;
+            action = ", reopen logs";
+            break;
+#endif
+
+        case ngx_signal_value(NGX_RECONFIGURE_SIGNAL):
+        case ngx_signal_value(NGX_REOPEN_SIGNAL):
+        case ngx_signal_value(NGX_PAUSE_SIGNAL):
+        case ngx_signal_value(NGX_CHANGEBIN_SIGNAL):
+            action = ", ignoring";
+            break;
+        }
+
         break;
+    }
 
-    case ngx_signal_value(NGX_REOPEN_SIGNAL):
-        ngx_reopen = 1;
-        break;
+    ngx_log_error(NGX_LOG_INFO, ngx_cycle->log, 0,
+                  "signal %d (%s) received%s", signo, sig->signame, action);
 
-    case ngx_signal_value(NGX_CHANGEBIN_SIGNAL):
-        ngx_change_binary = 1;
-        break;
+    if (signo == SIGCHLD) {
+        ngx_process_get_status();
     }
 
     ngx_set_errno(err);
--- a/src/os/unix/ngx_process.c
+++ b/src/os/unix/ngx_process.c
@@ -112,7 +112,7 @@ static void ngx_exec_proc(ngx_cycle_t *c
 }
 
 
-void ngx_signal_processes(ngx_cycle_t *cycle, ngx_int_t signal)
+void ngx_signal_processes(ngx_cycle_t *cycle, ngx_int_t signo)
 {
     ngx_uint_t  i;
 
@@ -122,24 +122,26 @@ void ngx_signal_processes(ngx_cycle_t *c
             continue;
         }
 
+#if 0
         if (ngx_processes[i].exited) {
             if (i != --ngx_last_process) {
                 ngx_processes[i--] = ngx_processes[ngx_last_process];
             }
             continue;
         }
+#endif
 
         ngx_log_debug2(NGX_LOG_DEBUG_CORE, cycle->log, 0,
                        "kill (" PID_T_FMT ", %d)" ,
-                       ngx_processes[i].pid, signal);
+                       ngx_processes[i].pid, signo);
 
-        if (kill(ngx_processes[i].pid, signal) == -1) {
+        if (kill(ngx_processes[i].pid, signo) == -1) {
             ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
-                          "kill(%d, %d) failed", ngx_processes[i].pid, signal);
+                          "kill(%d, %d) failed", ngx_processes[i].pid, signo);
             continue;
         }
 
-        if (signal != ngx_signal_value(NGX_REOPEN_SIGNAL)) {
+        if (signo != ngx_signal_value(NGX_REOPEN_SIGNAL)) {
             ngx_processes[i].exiting = 1;
         }
     }
@@ -151,7 +153,7 @@ void ngx_respawn_processes(ngx_cycle_t *
     ngx_uint_t  i;
 
     for (i = 0; i < ngx_last_process; i++) {
-        if (!ngx_processes[i].exited) {
+        if (ngx_processes[i].exiting || !ngx_processes[i].exited) {
             continue;
         }
 
@@ -212,11 +214,7 @@ void ngx_process_get_status()
         for (i = 0; i < ngx_last_process; i++) {
             if (ngx_processes[i].pid == pid) {
                 ngx_processes[i].status = status;
-
-                if (!ngx_processes[i].exiting) {
-                    ngx_processes[i].exited = 1;
-                }
-
+                ngx_processes[i].exited = 1;
                 process = ngx_processes[i].name;
                 break;
             }
--- a/src/os/unix/ngx_process.h
+++ b/src/os/unix/ngx_process.h
@@ -29,10 +29,11 @@ typedef struct {
 } ngx_exec_ctx_t;
 
 
-#define NGX_PROCESS_SINGLE       0
-#define NGX_PROCESS_MASTER       1
-#define NGX_PROCESS_WORKER       2
-#define NGX_PROCESS_MASTER_QUIT  3
+#define NGX_PROCESS_SINGLE   0
+#define NGX_PROCESS_MASTER   1
+#define NGX_PROCESS_WORKER   2
+#define NGX_PROCESS_QUITING  3
+#define NGX_PROCESS_PAUSED   4
 
 #define NGX_MAX_PROCESSES  1024
 
@@ -47,7 +48,7 @@ ngx_int_t ngx_spawn_process(ngx_cycle_t 
                             ngx_spawn_proc_pt proc, void *data,
                             char *name, ngx_int_t respawn);
 ngx_int_t ngx_exec(ngx_cycle_t *cycle, ngx_exec_ctx_t *ctx);
-void ngx_signal_processes(ngx_cycle_t *cycle, ngx_int_t signal);
+void ngx_signal_processes(ngx_cycle_t *cycle, ngx_int_t signo);
 void ngx_respawn_processes(ngx_cycle_t *cycle);
 void ngx_process_get_status(void);