]> git.kaiwu.me - nginx.git/commitdiff
Cancelable timers are now preserved if there are other timers.
authorMaxim Dounin <mdounin@mdounin.ru>
Tue, 7 Mar 2017 15:51:15 +0000 (18:51 +0300)
committerMaxim Dounin <mdounin@mdounin.ru>
Tue, 7 Mar 2017 15:51:15 +0000 (18:51 +0300)
There is no need to cancel timers early if there are other timers blocking
shutdown anyway.  Preserving such timers allows nginx to continue some
periodic work till the shutdown is actually possible.

With the new approach, timers with ev->cancelable are simply ignored when
checking if there are any timers left during shutdown.

src/event/ngx_event_timer.c
src/event/ngx_event_timer.h
src/os/unix/ngx_process_cycle.c
src/os/win32/ngx_process_cycle.c

index 8f547b215ac93389a7480aef4d85dac6586674e6..20e52f45eb7bd17fcc5805a4e2041abbee6076ff 100644 (file)
@@ -96,43 +96,31 @@ ngx_event_expire_timers(void)
 }
 
 
-void
-ngx_event_cancel_timers(void)
+ngx_int_t
+ngx_event_no_timers_left(void)
 {
     ngx_event_t        *ev;
     ngx_rbtree_node_t  *node, *root, *sentinel;
 
     sentinel = ngx_event_timer_rbtree.sentinel;
+    root = ngx_event_timer_rbtree.root;
 
-    for ( ;; ) {
-        root = ngx_event_timer_rbtree.root;
-
-        if (root == sentinel) {
-            return;
-        }
-
-        node = ngx_rbtree_min(root, sentinel);
+    if (root == sentinel) {
+        return NGX_OK;
+    }
 
+    for (node = ngx_rbtree_min(root, sentinel);
+         node;
+         node = ngx_rbtree_next(&ngx_event_timer_rbtree, node))
+    {
         ev = (ngx_event_t *) ((char *) node - offsetof(ngx_event_t, timer));
 
         if (!ev->cancelable) {
-            return;
+            return NGX_AGAIN;
         }
+    }
 
-        ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
-                       "event timer cancel: %d: %M",
-                       ngx_event_ident(ev->data), ev->timer.key);
-
-        ngx_rbtree_delete(&ngx_event_timer_rbtree, &ev->timer);
-
-#if (NGX_DEBUG)
-        ev->timer.left = NULL;
-        ev->timer.right = NULL;
-        ev->timer.parent = NULL;
-#endif
-
-        ev->timer_set = 0;
+    /* only cancelable timers left */
 
-        ev->handler(ev);
-    }
+    return NGX_OK;
 }
index 99f8a48fbda7902980fd48cd1a5e318251f4ea6c..be81b157f41662cc6f4a88ddd8f5a0a687e11d23 100644 (file)
@@ -22,7 +22,7 @@
 ngx_int_t ngx_event_timer_init(ngx_log_t *log);
 ngx_msec_t ngx_event_find_timer(void);
 void ngx_event_expire_timers(void);
-void ngx_event_cancel_timers(void);
+ngx_int_t ngx_event_no_timers_left(void);
 
 
 extern ngx_rbtree_t  ngx_event_timer_rbtree;
index 5c4e21dfd9e7f7cf85e2a5e49d89ddefe260cf1b..d0c61143e883dcfb812d707d6695ce5901b9ac78 100644 (file)
@@ -738,10 +738,7 @@ ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data)
     for ( ;; ) {
 
         if (ngx_exiting) {
-            ngx_event_cancel_timers();
-
-            if (ngx_event_timer_rbtree.root == ngx_event_timer_rbtree.sentinel)
-            {
+            if (ngx_event_no_timers_left() == NGX_OK) {
                 ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting");
 
                 ngx_worker_process_exit(cycle);
index 99fec54e36afa7da397614a83f5713c3530ab386..5b2df3858bc2caedff403d8f91bd42c1eb377d5f 100644 (file)
@@ -782,11 +782,7 @@ ngx_worker_thread(void *data)
     while (!ngx_quit) {
 
         if (ngx_exiting) {
-            ngx_event_cancel_timers();
-
-            if (ngx_event_timer_rbtree.root
-                == ngx_event_timer_rbtree.sentinel)
-            {
+            if (ngx_event_no_timers_left() == NGX_OK) {
                 break;
             }
         }