diff --git a/src/event/ngx_event.h b/src/event/ngx_event.h index 6531ec7ad..a1643a134 100644 --- a/src/event/ngx_event.h +++ b/src/event/ngx_event.h @@ -136,6 +136,8 @@ struct ngx_event_s { unsigned channel:1; unsigned resolver:1; + unsigned cancelable:1; + #if 0 diff --git a/src/event/ngx_event_timer.c b/src/event/ngx_event_timer.c index b7f2ade38..8f547b215 100644 --- a/src/event/ngx_event_timer.c +++ b/src/event/ngx_event_timer.c @@ -94,3 +94,45 @@ ngx_event_expire_timers(void) ev->handler(ev); } } + + +void +ngx_event_cancel_timers(void) +{ + ngx_event_t *ev; + ngx_rbtree_node_t *node, *root, *sentinel; + + sentinel = ngx_event_timer_rbtree.sentinel; + + for ( ;; ) { + root = ngx_event_timer_rbtree.root; + + if (root == sentinel) { + return; + } + + node = ngx_rbtree_min(root, sentinel); + + ev = (ngx_event_t *) ((char *) node - offsetof(ngx_event_t, timer)); + + if (!ev->cancelable) { + return; + } + + 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; + + ev->handler(ev); + } +} diff --git a/src/event/ngx_event_timer.h b/src/event/ngx_event_timer.h index df55d3cd6..99f8a48fb 100644 --- a/src/event/ngx_event_timer.h +++ b/src/event/ngx_event_timer.h @@ -22,6 +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); extern ngx_rbtree_t ngx_event_timer_rbtree; diff --git a/src/os/unix/ngx_process_cycle.c b/src/os/unix/ngx_process_cycle.c index 196394488..51cf72544 100644 --- a/src/os/unix/ngx_process_cycle.c +++ b/src/os/unix/ngx_process_cycle.c @@ -809,6 +809,8 @@ ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data) } } + ngx_event_cancel_timers(); + if (ngx_event_timer_rbtree.root == ngx_event_timer_rbtree.sentinel) { ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting"); diff --git a/src/os/win32/ngx_process_cycle.c b/src/os/win32/ngx_process_cycle.c index 183efc896..7bfb28119 100644 --- a/src/os/win32/ngx_process_cycle.c +++ b/src/os/win32/ngx_process_cycle.c @@ -821,6 +821,8 @@ ngx_worker_thread(void *data) } } + ngx_event_cancel_timers(); + if (ngx_event_timer_rbtree.root == ngx_event_timer_rbtree.sentinel) {