summaryrefslogtreecommitdiffhomepage
path: root/src/nxt_timer.h
blob: de11e9e37de8fdba5343124f580b37f449aa0b33 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139

/*
 * Copyright (C) Igor Sysoev
 * Copyright (C) NGINX, Inc.
 */

#ifndef _NXT_TIMER_H_INCLUDED_
#define _NXT_TIMER_H_INCLUDED_


/* Valid values are between 1ms to 255ms. */
#define NXT_TIMER_DEFAULT_PRECISION  100
//#define NXT_TIMER_DEFAULT_PRECISION  1


#if (NXT_DEBUG)
#define NXT_TIMER             { NXT_RBTREE_NODE_INIT, 0, 0, 0,                \
                                NULL, NULL, NULL, NULL, -1 }

#else
#define NXT_TIMER             { NXT_RBTREE_NODE_INIT, 0, 0, 0,                \
                                NULL, NULL, NULL, NULL }
#endif


typedef struct {
    /* The rbtree node must be the first field. */
    NXT_RBTREE_NODE           (node);

    uint8_t                   state;
    uint8_t                   precision;
    nxt_msec_t                time;

    nxt_work_queue_t          *work_queue;
    nxt_work_handler_t        handler;

    nxt_task_t                *task;
    nxt_log_t                 *log;
#if (NXT_DEBUG)
    int32_t                   ident;
#endif
} nxt_timer_t;


typedef struct {
    nxt_msec_t                time;
    nxt_timer_t               *timer;
} nxt_timer_change_t;


typedef struct {
    nxt_rbtree_t              tree;

    /* An overflown milliseconds counter. */
    nxt_msec_t                now;

    nxt_uint_t                mchanges;
    nxt_uint_t                nchanges;

   nxt_timer_change_t         *changes;
} nxt_timers_t;


#define nxt_timer_data(obj, type, timer)                                      \
    nxt_container_of(obj, type, timer)


/*
 * When timer resides in rbtree all links of its node are not NULL.
 * A parent link is the nearst to other timer flags.
 */

#define nxt_timer_is_in_tree(timer)                                           \
    ((timer)->node.parent != NULL)

#define nxt_timer_in_tree_set(timer)
    /* Noop, because rbtree insertion sets a node's parent link. */

#define nxt_timer_in_tree_clear(timer)                                        \
    (timer)->node.parent = NULL


#define NXT_TIMER_DISABLED  0
#define NXT_TIMER_BLOCKED   1
#define NXT_TIMER_ACTIVE    2


#if (NXT_DEBUG)

#define nxt_timer_ident(timer, val)                                           \
    (timer)->ident = (val)

#else

#define nxt_timer_ident(timer, val)

#endif


nxt_inline nxt_timer_t *
nxt_timer_create(int32_t ident)
{
    nxt_timer_t  *timer;

    timer = nxt_zalloc(sizeof(nxt_timer_t));
    if (timer == NULL) {
        return NULL;
    }

    timer->precision = NXT_TIMER_DEFAULT_PRECISION;
#if (NXT_DEBUG)
    timer->ident = ident;
#endif

    return timer;
}


nxt_int_t nxt_timers_init(nxt_timers_t *timers, nxt_uint_t mchanges);
NXT_EXPORT void nxt_timer_add(nxt_event_engine_t *engine, nxt_timer_t *timer,
    nxt_msec_t timeout);
NXT_EXPORT void nxt_timer_delete(nxt_event_engine_t *engine,
    nxt_timer_t *timer);
nxt_msec_t nxt_timer_find(nxt_event_engine_t *engine);
void nxt_timer_expire(nxt_thread_t *thr, nxt_msec_t now);

#if (NXT_DEBUG)

NXT_EXPORT void nxt_timer_disable(nxt_timer_t *timer);

#else

#define nxt_timer_disable(timer)                                              \
    (timer)->state = NXT_TIMER_DISABLED

#endif


#endif /* _NXT_TIMER_H_INCLUDED_ */