diff src/core/ngx_cycle.c @ 6930:97c99bb43737

Introduced worker_shutdown_timeout. The directive configures a timeout to be used when gracefully shutting down worker processes. When the timer expires, nginx will try to close all the connections currently open to facilitate shutdown.
author Maxim Dounin <mdounin@mdounin.ru>
date Tue, 07 Mar 2017 18:51:16 +0300
parents 30b6f1ff192b
children 99c87770b81b
line wrap: on
line diff
--- a/src/core/ngx_cycle.c
+++ b/src/core/ngx_cycle.c
@@ -15,6 +15,7 @@ static ngx_int_t ngx_init_zone_pool(ngx_
     ngx_shm_zone_t *shm_zone);
 static ngx_int_t ngx_test_lockfile(u_char *file, ngx_log_t *log);
 static void ngx_clean_old_cycles(ngx_event_t *ev);
+static void ngx_shutdown_timer_handler(ngx_event_t *ev);
 
 
 volatile ngx_cycle_t  *ngx_cycle;
@@ -22,6 +23,7 @@ ngx_array_t            ngx_old_cycles;
 
 static ngx_pool_t     *ngx_temp_pool;
 static ngx_event_t     ngx_cleaner_event;
+static ngx_event_t     ngx_shutdown_event;
 
 ngx_uint_t             ngx_test_config;
 ngx_uint_t             ngx_dump_config;
@@ -1333,3 +1335,54 @@ ngx_clean_old_cycles(ngx_event_t *ev)
         ngx_old_cycles.nelts = 0;
     }
 }
+
+
+void
+ngx_set_shutdown_timer(ngx_cycle_t *cycle)
+{
+    ngx_core_conf_t  *ccf;
+
+    ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
+
+    if (ccf->shutdown_timeout) {
+        ngx_shutdown_event.handler = ngx_shutdown_timer_handler;
+        ngx_shutdown_event.data = cycle;
+        ngx_shutdown_event.log = cycle->log;
+        ngx_shutdown_event.cancelable = 1;
+
+        ngx_add_timer(&ngx_shutdown_event, ccf->shutdown_timeout);
+    }
+}
+
+
+static void
+ngx_shutdown_timer_handler(ngx_event_t *ev)
+{
+    ngx_uint_t         i;
+    ngx_cycle_t       *cycle;
+    ngx_connection_t  *c;
+
+    cycle = ev->data;
+
+    c = cycle->connections;
+
+    for (i = 0; i < cycle->connection_n; i++) {
+
+        if (c[i].fd == (ngx_socket_t) -1
+            || c[i].read == NULL
+            || c[i].read->accept
+            || c[i].read->channel
+            || c[i].read->resolver)
+        {
+            continue;
+        }
+
+        ngx_log_debug1(NGX_LOG_DEBUG_CORE, ev->log, 0,
+                       "*%uA shutdown timeout", c[i].number);
+
+        c[i].close = 1;
+        c[i].error = 1;
+
+        c[i].read->handler(c[i].read);
+    }
+}