1e18a033bSKonstantin Ananyev
2e18a033bSKonstantin Ananyev/*
3e18a033bSKonstantin Ananyev * Copyright (C) Igor Sysoev
4e18a033bSKonstantin Ananyev * Copyright (C) Nginx, Inc.
5e18a033bSKonstantin Ananyev */
6e18a033bSKonstantin Ananyev
7e18a033bSKonstantin Ananyev
8e18a033bSKonstantin Ananyev#ifndef _NGX_EVENT_TIMER_H_INCLUDED_
9e18a033bSKonstantin Ananyev#define _NGX_EVENT_TIMER_H_INCLUDED_
10e18a033bSKonstantin Ananyev
11e18a033bSKonstantin Ananyev
12e18a033bSKonstantin Ananyev#include <ngx_config.h>
13e18a033bSKonstantin Ananyev#include <ngx_core.h>
14e18a033bSKonstantin Ananyev#include <ngx_event.h>
15e18a033bSKonstantin Ananyev
16e18a033bSKonstantin Ananyev
17e18a033bSKonstantin Ananyev#define NGX_TIMER_INFINITE  (ngx_msec_t) -1
18e18a033bSKonstantin Ananyev
19e18a033bSKonstantin Ananyev#define NGX_TIMER_LAZY_DELAY  300
20e18a033bSKonstantin Ananyev
21e18a033bSKonstantin Ananyev
22e18a033bSKonstantin Ananyevngx_int_t ngx_event_timer_init(ngx_log_t *log);
23e18a033bSKonstantin Ananyevngx_msec_t ngx_event_find_timer(void);
24e18a033bSKonstantin Ananyevvoid ngx_event_expire_timers(void);
25e18a033bSKonstantin Ananyevngx_int_t ngx_event_no_timers_left(void);
26e18a033bSKonstantin Ananyev
27e18a033bSKonstantin Ananyev
28e18a033bSKonstantin Ananyevextern ngx_rbtree_t  ngx_event_timer_rbtree;
29e18a033bSKonstantin Ananyev
30e18a033bSKonstantin Ananyev
31e18a033bSKonstantin Ananyevstatic ngx_inline void
32e18a033bSKonstantin Ananyevngx_event_del_timer(ngx_event_t *ev)
33e18a033bSKonstantin Ananyev{
34e18a033bSKonstantin Ananyev    ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
35e18a033bSKonstantin Ananyev                   "event timer del: %d: %M",
36e18a033bSKonstantin Ananyev                    ngx_event_ident(ev->data), ev->timer.key);
37e18a033bSKonstantin Ananyev
38e18a033bSKonstantin Ananyev    ngx_rbtree_delete(&ngx_event_timer_rbtree, &ev->timer);
39e18a033bSKonstantin Ananyev
40e18a033bSKonstantin Ananyev#if (NGX_DEBUG)
41e18a033bSKonstantin Ananyev    ev->timer.left = NULL;
42e18a033bSKonstantin Ananyev    ev->timer.right = NULL;
43e18a033bSKonstantin Ananyev    ev->timer.parent = NULL;
44e18a033bSKonstantin Ananyev#endif
45e18a033bSKonstantin Ananyev
46e18a033bSKonstantin Ananyev    ev->timer_set = 0;
47e18a033bSKonstantin Ananyev}
48e18a033bSKonstantin Ananyev
49e18a033bSKonstantin Ananyev
50e18a033bSKonstantin Ananyevstatic ngx_inline void
51e18a033bSKonstantin Ananyevngx_event_add_timer(ngx_event_t *ev, ngx_msec_t timer)
52e18a033bSKonstantin Ananyev{
53e18a033bSKonstantin Ananyev    ngx_msec_t      key;
54e18a033bSKonstantin Ananyev    ngx_msec_int_t  diff;
55e18a033bSKonstantin Ananyev
56e18a033bSKonstantin Ananyev    key = ngx_current_msec + timer;
57e18a033bSKonstantin Ananyev
58e18a033bSKonstantin Ananyev    if (ev->timer_set) {
59e18a033bSKonstantin Ananyev
60e18a033bSKonstantin Ananyev        /*
61e18a033bSKonstantin Ananyev         * Use a previous timer value if difference between it and a new
62e18a033bSKonstantin Ananyev         * value is less than NGX_TIMER_LAZY_DELAY milliseconds: this allows
63e18a033bSKonstantin Ananyev         * to minimize the rbtree operations for fast connections.
64e18a033bSKonstantin Ananyev         */
65e18a033bSKonstantin Ananyev
66e18a033bSKonstantin Ananyev        diff = (ngx_msec_int_t) (key - ev->timer.key);
67e18a033bSKonstantin Ananyev
68e18a033bSKonstantin Ananyev        if (ngx_abs(diff) < NGX_TIMER_LAZY_DELAY) {
69e18a033bSKonstantin Ananyev            ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0,
70e18a033bSKonstantin Ananyev                           "event timer: %d, old: %M, new: %M",
71e18a033bSKonstantin Ananyev                            ngx_event_ident(ev->data), ev->timer.key, key);
72e18a033bSKonstantin Ananyev            return;
73e18a033bSKonstantin Ananyev        }
74e18a033bSKonstantin Ananyev
75e18a033bSKonstantin Ananyev        ngx_del_timer(ev);
76e18a033bSKonstantin Ananyev    }
77e18a033bSKonstantin Ananyev
78e18a033bSKonstantin Ananyev    ev->timer.key = key;
79e18a033bSKonstantin Ananyev
80e18a033bSKonstantin Ananyev    ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0,
81e18a033bSKonstantin Ananyev                   "event timer add: %d: %M:%M",
82e18a033bSKonstantin Ananyev                    ngx_event_ident(ev->data), timer, ev->timer.key);
83e18a033bSKonstantin Ananyev
84e18a033bSKonstantin Ananyev    ngx_rbtree_insert(&ngx_event_timer_rbtree, &ev->timer);
85e18a033bSKonstantin Ananyev
86e18a033bSKonstantin Ananyev    ev->timer_set = 1;
87e18a033bSKonstantin Ananyev}
88e18a033bSKonstantin Ananyev
89e18a033bSKonstantin Ananyev
90e18a033bSKonstantin Ananyev#endif /* _NGX_EVENT_TIMER_H_INCLUDED_ */
91