Skip to content

Commit

Permalink
Cancelable timers are now preserved if there are other timers.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
mdounin committed Mar 7, 2017
1 parent 0212c7f commit 1a58418
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 36 deletions.
40 changes: 14 additions & 26 deletions src/event/ngx_event_timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
2 changes: 1 addition & 1 deletion src/event/ngx_event_timer.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
5 changes: 1 addition & 4 deletions src/os/unix/ngx_process_cycle.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
6 changes: 1 addition & 5 deletions src/os/win32/ngx_process_cycle.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Expand Down

0 comments on commit 1a58418

Please sign in to comment.