changeset 226:b0c1e21e68db

nginx-0.0.1-2004-01-14-00:33:59 import
author Igor Sysoev <igor@sysoev.ru>
date Tue, 13 Jan 2004 21:33:59 +0000
parents 2e9a8a14a0cf
children 2ba3477070ac
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, 125 insertions(+), 37 deletions(-) [+]
line wrap: on
line diff
--- a/src/core/nginx.c
+++ b/src/core/nginx.c
@@ -16,6 +16,7 @@ typedef struct {
 
 typedef struct {
      ngx_file_t    pid;
+     char         *name;
      char *const  *argv;
 } ngx_master_ctx_t;
 
@@ -23,7 +24,7 @@ typedef struct {
 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_pid_t ngx_exec_new_binary(ngx_cycle_t *cycle, char *const *argv);
 static ngx_int_t ngx_core_module_init(ngx_cycle_t *cycle);
 
 
@@ -75,8 +76,9 @@ uid_t      user;
 u_int ngx_connection_counter;
 
 ngx_int_t  ngx_process;
+ngx_pid_t  ngx_new_binary;
+
 ngx_int_t  ngx_inherited;
-
 ngx_int_t  ngx_signal;
 ngx_int_t  ngx_reap;
 ngx_int_t  ngx_terminate;
@@ -201,6 +203,7 @@ int main(int argc, char *const *argv, ch
     len = ngx_snprintf(pid, /* STUB */ 10, PID_T_FMT, ngx_getpid());
     ngx_memzero(&ctx.pid, sizeof(ngx_file_t));
     ctx.pid.name = ngx_inherited ? ccf->newpid : ccf->pid;
+    ctx.name = ccf->pid.data;
 
     ctx.pid.fd = ngx_open_file(ctx.pid.name.data, NGX_FILE_RDWR,
                                NGX_FILE_CREATE_OR_OPEN);
@@ -230,13 +233,16 @@ int main(int argc, char *const *argv, ch
 }
 
 
+/* TODO: broken single process */
+
 static void ngx_master_process_cycle(ngx_cycle_t *cycle, ngx_master_ctx_t *ctx)
 {
-    int             signo;
-    ngx_msec_t      delay;
-    struct timeval  tv;
-    ngx_uint_t      i, live, mark;
-    sigset_t        set, wset;
+    int              signo;
+    char            *name;
+    sigset_t         set, wset;
+    struct timeval   tv;
+    ngx_uint_t       i, live, mark;
+    ngx_msec_t       delay;
 
     delay = 125;
 
@@ -257,6 +263,7 @@ static void ngx_master_process_cycle(ngx
     }
 
     ngx_signal = 0;
+    ngx_new_binary = 0;
     signo = 0;
     mark = 1;
 
@@ -266,6 +273,7 @@ static void ngx_master_process_cycle(ngx
         if (ngx_process == NGX_PROCESS_MASTER) {
             ngx_spawn_process(cycle, ngx_worker_process_cycle, NULL,
                               "worker process", NGX_PROCESS_RESPAWN);
+            mark = 1;
 
         } else {
             ngx_init_temp_number();
@@ -280,7 +288,7 @@ static void ngx_master_process_cycle(ngx
             }
         }
 
-        /* a cycle with the same configuration */
+        /* a cycle with the same configuration because a new one is invalid */
 
         for ( ;; ) {
 
@@ -290,8 +298,8 @@ static void ngx_master_process_cycle(ngx
 
                 if (ngx_process == NGX_PROCESS_MASTER) {
                     if (signo) {
-                        ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
-                                       "signal cycle");
+                        ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
+                                       "signal cycle: %d, %d", signo, mark);
 
                         if (sigprocmask(SIG_UNBLOCK, &set, NULL) == -1) {
                             ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
@@ -330,14 +338,19 @@ static void ngx_master_process_cycle(ngx
                         ngx_signal = 0;
 
                     } else {
+                        ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
+                                       "sigsuspend");
+
                         sigsuspend(&wset);
 
                         ngx_gettimeofday(&tv);
                         ngx_time_update(tv.tv_sec);
+
+                        ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
+                                       "wake up");
                     }
 
-                /* TODO: broken */
-                } else if (ngx_process == NGX_PROCESS_SINGLE) {
+                } else { /* NGX_PROCESS_SINGLE */
                     ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
                                    "worker cycle");
 
@@ -345,8 +358,12 @@ static void ngx_master_process_cycle(ngx
                 }
 
                 if (ngx_reap) {
+                    ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
+                                   "reap childs");
+
                     live = 0;
                     for (i = 0; i < ngx_last_process; i++) {
+
                         if (ngx_processes[i].exiting
                             && !ngx_processes[i].exited)
                         {
@@ -354,22 +371,33 @@ static void ngx_master_process_cycle(ngx
                             continue;
                         }
 
-                        if (i != --ngx_last_process) {
-                            ngx_processes[i--] =
+                        if (ngx_processes[i].exited) {
+                            if (ngx_processes[i].pid == ngx_new_binary) {
+                                ngx_new_binary = 0;
+                            }
+
+                            if (i != --ngx_last_process) {
+                                ngx_processes[i--] =
                                                ngx_processes[ngx_last_process];
+                            }
                         }
                     }
 
                     if (!live) {
                         if (ngx_terminate || ngx_quit) {
-                            if (ngx_delete_file(ctx->pid.name.data)
-                                                             == NGX_FILE_ERROR)
-                            {
+
+                            if (ngx_inherited && getppid() > 1) {
+                                name = ctx->pid.name.data;
+
+                            } else {
+                                name = ctx->name;
+                            }
+
+                            if (ngx_delete_file(name) == NGX_FILE_ERROR) {
                                 ngx_log_error(NGX_LOG_ALERT, cycle->log,
                                               ngx_errno,
                                               ngx_delete_file_n
-                                              " \"%s\" failed",
-                                              ctx->pid.name.data);
+                                              " \"%s\" failed", name);
                             }
 
                             ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "exit");
@@ -377,6 +405,7 @@ static void ngx_master_process_cycle(ngx
 
                         } else {
                             signo = 0;
+                            mark = 0;
                         }
                     }
                 }
@@ -386,14 +415,24 @@ static void ngx_master_process_cycle(ngx
                         signo = SIGKILL;
                     } else {
                         signo = ngx_signal_value(NGX_TERMINATE_SIGNAL);
+                        if (mark == 0) {
+                            mark = 1;
+                        }
                     }
+                    ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
+                                   "mark: %d", mark);
 
                 } else if (ngx_quit) {
                     signo = ngx_signal_value(NGX_SHUTDOWN_SIGNAL);
+                    if (mark == 0) {
+                        mark = 1;
+                    }
 
                 } else {
 
                     if (ngx_reap) {
+                        ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
+                                       "respawn processes");
                         ngx_respawn_processes(cycle);
                     }
 
@@ -408,7 +447,7 @@ static void ngx_master_process_cycle(ngx
                         ngx_change_binary = 0;
                         ngx_log_error(NGX_LOG_INFO, cycle->log, 0,
                                       "changing binary");
-                        ngx_exec_new_binary(cycle, ctx->argv);
+                        ngx_new_binary = ngx_exec_new_binary(cycle, ctx->argv);
                     }
 
                     if (ngx_reconfigure) {
@@ -419,9 +458,12 @@ static void ngx_master_process_cycle(ngx
                     }
 
                     if (ngx_reopen) {
+                        ngx_reopen = 0;
+
+                        /* STUB */
                         mark = 1;
-                        ngx_reopen = 0;
                         signo = ngx_signal_value(NGX_SHUTDOWN_SIGNAL);
+
                         ngx_log_error(NGX_LOG_INFO, cycle->log, 0,
                                       "reopening logs");
                         ngx_reopen_files(cycle);
@@ -431,8 +473,17 @@ static void ngx_master_process_cycle(ngx
                 if (signo) {
                     if (mark == 1) {
                         for (i = 0; i < ngx_last_process; i++) {
+                            ngx_log_debug1(NGX_LOG_DEBUG_EVENT,
+                                           cycle->log, 0,
+                                           "proc " PID_T_FMT,
+                                           ngx_processes[i].pid);
+
                             if (!ngx_processes[i].detached) {
                                 ngx_processes[i].signal = 1;
+                                ngx_log_debug1(NGX_LOG_DEBUG_EVENT,
+                                               cycle->log, 0,
+                                               "mark " PID_T_FMT,
+                                               ngx_processes[i].pid);
                             }
                         }
                         mark = -1;
@@ -446,6 +497,11 @@ static void ngx_master_process_cycle(ngx
                     ngx_reap = 0;
                 }
 
+                /* STUB */
+                if (ngx_reopen) {
+                    break;
+                }
+
                 if (ngx_reconfigure) {
                     break;
                 }
@@ -602,10 +658,11 @@ static ngx_int_t ngx_add_inherited_socke
 }
 
 
-static void ngx_exec_new_binary(ngx_cycle_t *cycle, char *const *argv)
+static ngx_pid_t ngx_exec_new_binary(ngx_cycle_t *cycle, char *const *argv)
 {
     char             *env[2], *var, *p;
     ngx_int_t         i;
+    ngx_pid_t         pid;
     ngx_exec_ctx_t    ctx;
     ngx_listening_t  *ls;
 
@@ -628,9 +685,11 @@ static void ngx_exec_new_binary(ngx_cycl
     env[1] = NULL;
     ctx.envp = (char *const *) &env;
 
-    ngx_exec(cycle, &ctx);
+    pid = ngx_exec(cycle, &ctx);
 
     ngx_free(var);
+
+    return pid;
 }
 
 
--- a/src/os/unix/ngx_os.h
+++ b/src/os/unix/ngx_os.h
@@ -50,7 +50,9 @@ extern int          ngx_inherited_nonblo
 
 
 extern ngx_int_t    ngx_process;
+extern ngx_pid_t    ngx_new_binary;
 
+extern ngx_int_t    ngx_inherited;
 extern ngx_int_t    ngx_signal;
 extern ngx_int_t    ngx_reap;
 extern ngx_int_t    ngx_quit;
--- a/src/os/unix/ngx_posix_init.c
+++ b/src/os/unix/ngx_posix_init.c
@@ -42,6 +42,8 @@ ngx_signal_t  signals[] = {
       "SIG" ngx_value(NGX_CHANGEBIN_SIGNAL),
       ngx_signal_handler },
 
+    { SIGINT, "SIGINT", ngx_signal_handler },
+
     { SIGCHLD, "SIGCHLD", ngx_signal_handler },
 
     { SIGPIPE, "SIGPIPE, SIG_IGN", SIG_IGN },
@@ -93,10 +95,12 @@ void ngx_signal_handler(int signo)
 {
     char            *action;
     struct timeval   tv;
+    ngx_int_t        ignore;
     ngx_err_t        err;
     ngx_signal_t    *sig;
 
     ngx_signal = 1;
+    ignore = 0;
 
     err = ngx_errno;
 
@@ -138,11 +142,31 @@ void ngx_signal_handler(int signo)
             break;
 
         case ngx_signal_value(NGX_REOPEN_SIGNAL):
-            ngx_reopen = 1;
-            action = ", reopen logs";
-            break;
+            if (ngx_noaccept) {
+                action = ", ignoring";
+
+            } else {
+                ngx_reopen = 1;
+                action = ", reopen logs";
+                break;
+            }
 
         case ngx_signal_value(NGX_CHANGEBIN_SIGNAL):
+            if ((ngx_inherited && getppid() > 1)
+                || (!ngx_inherited && ngx_new_binary > 0))
+            {
+                /*
+                 * Ignore the signal in the new binary if its parent is
+                 * not the init process, i.e. the old binary's process
+                 * is still running.  Or ingore the signal in the old binary's
+                 * process if the new binary's process is already running.
+                 */
+
+                action = ", ignoring";
+                ignore = 1;
+                break;
+            }
+
             ngx_change_binary = 1;
             action = ", changing binary";
             break;
@@ -189,6 +213,13 @@ void ngx_signal_handler(int signo)
     ngx_log_error(NGX_LOG_INFO, ngx_cycle->log, 0,
                   "signal %d (%s) received%s", signo, sig->signame, action);
 
+    if (ignore) {
+        ngx_log_error(NGX_LOG_CRIT, ngx_cycle->log, 0,
+                      "the changing binary signal is ignored: "
+                      "you should shutdown or terminate "
+                      "before either old or new binary's process");
+    }
+
     if (signo == SIGCHLD) {
         ngx_process_get_status();
     }
--- a/src/os/unix/ngx_process.c
+++ b/src/os/unix/ngx_process.c
@@ -85,17 +85,10 @@ ngx_pid_t ngx_spawn_process(ngx_cycle_t 
 }
 
 
-ngx_int_t ngx_exec(ngx_cycle_t *cycle, ngx_exec_ctx_t *ctx)
+ngx_pid_t ngx_exec(ngx_cycle_t *cycle, ngx_exec_ctx_t *ctx)
 {
-    if (ngx_spawn_process(cycle, ngx_exec_proc, ctx, ctx->name,
-                                            NGX_PROCESS_DETACHED) == NGX_ERROR)
-    {
-        ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
-                      "can not spawn %s", ctx->name);
-        return NGX_ERROR;
-    }
-
-    return NGX_OK;
+    return ngx_spawn_process(cycle, ngx_exec_proc, ctx, ctx->name,
+                             NGX_PROCESS_DETACHED);
 }
 
 
@@ -154,6 +147,9 @@ void ngx_respawn_processes(ngx_cycle_t *
     ngx_uint_t  i;
 
     for (i = 0; i < ngx_last_process; i++) {
+        ngx_log_debug1(NGX_LOG_DEBUG_CORE, cycle->log, 0,
+                       "proc table " PID_T_FMT, ngx_processes[i].pid);
+
         if (ngx_processes[i].exiting || !ngx_processes[i].exited) {
             continue;
         }
--- a/src/os/unix/ngx_process.h
+++ b/src/os/unix/ngx_process.h
@@ -46,7 +46,7 @@ typedef struct {
 ngx_pid_t ngx_spawn_process(ngx_cycle_t *cycle,
                             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);
+ngx_pid_t ngx_exec(ngx_cycle_t *cycle, ngx_exec_ctx_t *ctx);
 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);