Klaus Demo nginx / 1a58418
Cancelable timers are now preserved if there are other timers. 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. Maxim Dounin 5 years ago
4 changed file(s) with 17 addition(s) and 36 deletion(s). Raw diff Collapse all Expand all
9595 }
9696
9797
98 void
99 ngx_event_cancel_timers(void)
98 ngx_int_t
99 ngx_event_no_timers_left(void)
100100 {
101101 ngx_event_t *ev;
102102 ngx_rbtree_node_t *node, *root, *sentinel;
103103
104104 sentinel = ngx_event_timer_rbtree.sentinel;
105 root = ngx_event_timer_rbtree.root;
105106
106 for ( ;; ) {
107 root = ngx_event_timer_rbtree.root;
107 if (root == sentinel) {
108 return NGX_OK;
109 }
108110
109 if (root == sentinel) {
110 return;
111 }
112
113 node = ngx_rbtree_min(root, sentinel);
114
111 for (node = ngx_rbtree_min(root, sentinel);
112 node;
113 node = ngx_rbtree_next(&ngx_event_timer_rbtree, node))
114 {
115115 ev = (ngx_event_t *) ((char *) node - offsetof(ngx_event_t, timer));
116116
117117 if (!ev->cancelable) {
118 return;
118 return NGX_AGAIN;
119119 }
120 }
120121
121 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
122 "event timer cancel: %d: %M",
123 ngx_event_ident(ev->data), ev->timer.key);
122 /* only cancelable timers left */
124123
125 ngx_rbtree_delete(&ngx_event_timer_rbtree, &ev->timer);
126
127 #if (NGX_DEBUG)
128 ev->timer.left = NULL;
129 ev->timer.right = NULL;
130 ev->timer.parent = NULL;
131 #endif
132
133 ev->timer_set = 0;
134
135 ev->handler(ev);
136 }
124 return NGX_OK;
137125 }
2121 ngx_int_t ngx_event_timer_init(ngx_log_t *log);
2222 ngx_msec_t ngx_event_find_timer(void);
2323 void ngx_event_expire_timers(void);
24 void ngx_event_cancel_timers(void);
24 ngx_int_t ngx_event_no_timers_left(void);
2525
2626
2727 extern ngx_rbtree_t ngx_event_timer_rbtree;
737737 for ( ;; ) {
738738
739739 if (ngx_exiting) {
740 ngx_event_cancel_timers();
741
742 if (ngx_event_timer_rbtree.root == ngx_event_timer_rbtree.sentinel)
743 {
740 if (ngx_event_no_timers_left() == NGX_OK) {
744741 ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting");
745742
746743 ngx_worker_process_exit(cycle);
781781 while (!ngx_quit) {
782782
783783 if (ngx_exiting) {
784 ngx_event_cancel_timers();
785
786 if (ngx_event_timer_rbtree.root
787 == ngx_event_timer_rbtree.sentinel)
788 {
784 if (ngx_event_no_timers_left() == NGX_OK) {
789785 break;
790786 }
791787 }