blob: 296c748ee620553ac0a56b65d664e9f4e4851429 [file] [log] [blame]
Igor Sysoev6b7cfab2003-01-21 17:36:01 +00001
Igor Sysoevfcce8d52003-01-23 18:47:54 +00002#include <ngx_config.h>
Igor Sysoevfcce8d52003-01-23 18:47:54 +00003#include <ngx_core.h>
Igor Sysoevfcce8d52003-01-23 18:47:54 +00004#include <ngx_event.h>
5
Igor Sysoevfcce8d52003-01-23 18:47:54 +00006
Igor Sysoevf5003d82003-12-04 14:53:00 +00007ngx_rbtree_t *ngx_event_timer_rbtree;
8
9
10int ngx_event_timer_init(ngx_cycle_t *cycle)
11{
12 ngx_event_timer_rbtree = &sentinel;
13 sentinel.left = &sentinel;
14 sentinel.right = &sentinel;
15 sentinel.parent = &sentinel;
16
17 return NGX_OK;
18}
19
20
21void ngx_event_timer_done(ngx_cycle_t *cycle)
22{
23}
24
25
26int ngx_event_find_timer(void)
27{
28 ngx_rbtree_t *node;
29
30 node = ngx_rbtree_min(ngx_event_timer_rbtree);
31
32 if (node == &sentinel) {
33 return 0;
34
35 } else {
36 return node->key * NGX_TIMER_RESOLUTION - ngx_elapsed_msec;
37 }
38}
39
40
41void ngx_event_expire_timers(ngx_msec_t timer)
42{
43 ngx_event_t *ev;
44 ngx_rbtree_t *node;
45
46 for ( ;; ) {
47 node = ngx_rbtree_min(ngx_event_timer_rbtree);
48
49 if (node == &sentinel) {
50 break;
51 }
52
53 if ((ngx_msec_t) node->key <=
54 (ngx_elapsed_msec + timer) / NGX_TIMER_RESOLUTION)
55 {
56 ev = (ngx_event_t *)
57 ((char *) node - offsetof(ngx_event_t, rbtree));
58
59 ngx_del_timer(ev);
60
61 if (ev->delayed) {
62 ev->delayed = 0;
63 if (ev->ready == 0) {
64 continue;
65 }
66
67 } else {
68 ev->timedout = 1;
69 }
70
71 ev->event_handler(ev);
72 continue;
73 }
74
75 break;
76 }
77}
78
79
80#if 0
81
Igor Sysoev0a280a32003-10-12 16:49:16 +000082/* TODO: in multithreaded enviroment all timer operations must be
Igor Sysoev890fc962003-07-20 21:15:59 +000083 protected by the single mutex */
84
85
Igor Sysoeva8fa0a62003-11-25 20:44:56 +000086#if 0
Igor Sysoev9d639522003-07-07 06:11:50 +000087static ngx_event_t *ngx_timer_queue, ngx_temp_timer_queue;
Igor Sysoeva8fa0a62003-11-25 20:44:56 +000088static int ngx_expire_timers;
89#endif
90
91static ngx_event_t *ngx_timer_queue;
92static ngx_msec_t *ngx_timer_delta;
Igor Sysoev9b25d692003-01-26 21:08:14 +000093static int ngx_timer_cur_queue;
Igor Sysoev9b25d692003-01-26 21:08:14 +000094static int ngx_timer_queue_num;
Igor Sysoevfcce8d52003-01-23 18:47:54 +000095
96
Igor Sysoev340b03b2003-07-04 15:10:33 +000097int ngx_event_timer_init(ngx_cycle_t *cycle)
Igor Sysoev6b7cfab2003-01-21 17:36:01 +000098{
Igor Sysoeva8fa0a62003-11-25 20:44:56 +000099 ngx_int_t i;
100 ngx_msec_t *new_delta;
Igor Sysoevbe2cfc32003-06-15 18:32:13 +0000101 ngx_event_t *new_queue;
Igor Sysoeva9830112003-05-19 16:39:14 +0000102 ngx_event_conf_t *ecf;
Igor Sysoevfcce8d52003-01-23 18:47:54 +0000103
Igor Sysoev340b03b2003-07-04 15:10:33 +0000104 ecf = ngx_event_get_conf(cycle->conf_ctx, ngx_event_core_module);
Igor Sysoeva9830112003-05-19 16:39:14 +0000105
Igor Sysoevbe2cfc32003-06-15 18:32:13 +0000106 if (ngx_timer_queue_num < ecf->timer_queues) {
107 ngx_test_null(new_queue,
Igor Sysoev340b03b2003-07-04 15:10:33 +0000108 ngx_alloc(ecf->timer_queues * sizeof(ngx_event_t),
109 cycle->log),
Igor Sysoevbe2cfc32003-06-15 18:32:13 +0000110 NGX_ERROR);
Igor Sysoevfcce8d52003-01-23 18:47:54 +0000111
Igor Sysoevbe2cfc32003-06-15 18:32:13 +0000112 for (i = 0; i < ngx_timer_queue_num; i++) {
113 new_queue[i] = ngx_timer_queue[i];
114 }
Igor Sysoevfcce8d52003-01-23 18:47:54 +0000115
Igor Sysoevbe2cfc32003-06-15 18:32:13 +0000116 if (ngx_timer_queue) {
117 ngx_free(ngx_timer_queue);
118 }
119
120 ngx_timer_queue = new_queue;
121
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000122 ngx_test_null(new_delta,
123 ngx_calloc(ecf->timer_queues * sizeof(ngx_msec_t),
124 cycle->log),
125 NGX_ERROR);
126
127 for (i = 0; i < ngx_timer_queue_num; i++) {
128 new_delta[i] = ngx_timer_delta[i];
129 }
130
131 if (ngx_timer_delta) {
132 ngx_free(ngx_timer_delta);
133 }
134
135 ngx_timer_delta = new_delta;
136
Igor Sysoevbe2cfc32003-06-15 18:32:13 +0000137 ngx_timer_queue_num = ecf->timer_queues;
138 ngx_timer_cur_queue = 0;
139
140 for (/* void */; i < ngx_timer_queue_num; i++) {
141 ngx_timer_queue[i].timer_prev = &ngx_timer_queue[i];
142 ngx_timer_queue[i].timer_next = &ngx_timer_queue[i];
143 }
Igor Sysoev340b03b2003-07-04 15:10:33 +0000144
145 } else if (ngx_timer_queue_num > ecf->timer_queues) {
146 /* STUB */
Igor Sysoev9d639522003-07-07 06:11:50 +0000147 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "NOT READY: timer");
Igor Sysoev340b03b2003-07-04 15:10:33 +0000148 exit(1);
Igor Sysoevfcce8d52003-01-23 18:47:54 +0000149 }
150
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000151#if 0
Igor Sysoev9d639522003-07-07 06:11:50 +0000152 ngx_temp_timer_queue.timer_prev = &ngx_temp_timer_queue;
153 ngx_temp_timer_queue.timer_next = &ngx_temp_timer_queue;
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000154#endif
Igor Sysoev9d639522003-07-07 06:11:50 +0000155
Igor Sysoeva9830112003-05-19 16:39:14 +0000156 return NGX_OK;;
157}
158
159
Igor Sysoev340b03b2003-07-04 15:10:33 +0000160void ngx_event_timer_done(ngx_cycle_t *cycle)
Igor Sysoeva9830112003-05-19 16:39:14 +0000161{
162 ngx_free(ngx_timer_queue);
Igor Sysoevbe2cfc32003-06-15 18:32:13 +0000163 ngx_timer_queue = NULL;
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000164
165 ngx_free(ngx_timer_delta);
166 ngx_timer_delta = NULL;
167
Igor Sysoev340b03b2003-07-04 15:10:33 +0000168 ngx_timer_queue_num = 0;
Igor Sysoevfcce8d52003-01-23 18:47:54 +0000169}
170
171
172void ngx_event_add_timer(ngx_event_t *ev, ngx_msec_t timer)
173{
Igor Sysoev9d639522003-07-07 06:11:50 +0000174 ngx_event_t *e, *queue;
Igor Sysoev0a280a32003-10-12 16:49:16 +0000175#if (NGX_DEBUG_EVENT)
176 ngx_connection_t *c;
177#endif
178
179 if (ev->timer_set) {
180 ngx_del_timer(ev);
181 }
Igor Sysoev6b7cfab2003-01-21 17:36:01 +0000182
183#if (NGX_DEBUG_EVENT)
Igor Sysoev0a280a32003-10-12 16:49:16 +0000184 c = ev->data;
185 ngx_log_debug(ev->log, "set timer: %d:%d:%d, slot: %d" _
186 c->fd _ ev->write _ timer _ ngx_timer_cur_queue);
Igor Sysoev6b7cfab2003-01-21 17:36:01 +0000187#endif
188
189 if (ev->timer_next || ev->timer_prev) {
190 ngx_log_error(NGX_LOG_ALERT, ev->log, 0, "timer already set");
191 return;
192 }
193
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000194 queue = &ngx_timer_queue[ngx_timer_cur_queue];
195 timer += ngx_timer_delta[ngx_timer_cur_queue++];
196
197 if (ngx_timer_cur_queue >= ngx_timer_queue_num) {
198 ngx_timer_cur_queue = 0;
199 }
200
201
202#if 0
Igor Sysoev9d639522003-07-07 06:11:50 +0000203 if (ngx_expire_timers) {
204 queue = &ngx_temp_timer_queue;
205
206 } else {
207 queue = &ngx_timer_queue[ngx_timer_cur_queue++];
208
209 if (ngx_timer_cur_queue >= ngx_timer_queue_num) {
210 ngx_timer_cur_queue = 0;
211 }
212 }
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000213#endif
Igor Sysoev9d639522003-07-07 06:11:50 +0000214
215 for (e = queue->timer_next;
216 e != queue && timer > e->timer_delta;
Igor Sysoev6b7cfab2003-01-21 17:36:01 +0000217 e = e->timer_next)
218 {
219 timer -= e->timer_delta;
220 }
221
222 ev->timer_delta = timer;
223
224 ev->timer_next = e;
225 ev->timer_prev = e->timer_prev;
226
227 e->timer_prev->timer_next = ev;
228 e->timer_prev = ev;
Igor Sysoev0a280a32003-10-12 16:49:16 +0000229
230 ev->timer_set = 1;
231
232 return;
Igor Sysoev6b7cfab2003-01-21 17:36:01 +0000233}
Igor Sysoev404326f2003-01-24 06:20:47 +0000234
235
Igor Sysoev9b25d692003-01-26 21:08:14 +0000236int ngx_event_find_timer(void)
237{
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000238 ngx_int_t i;
Igor Sysoev9b25d692003-01-26 21:08:14 +0000239 ngx_msec_t timer;
240
241 timer = NGX_MAX_MSEC;
242
243 for (i = 0; i < ngx_timer_queue_num; i++) {
244 if (ngx_timer_queue[i].timer_next == &ngx_timer_queue[i]) {
245 continue;
246 }
247
248 if (timer > ngx_timer_queue[i].timer_next->timer_delta) {
249 timer = ngx_timer_queue[i].timer_next->timer_delta;
250 }
251 }
252
253 if (timer == NGX_MAX_MSEC) {
254 return 0;
Igor Sysoev9b25d692003-01-26 21:08:14 +0000255 }
Igor Sysoev0a280a32003-10-12 16:49:16 +0000256
257 return timer;
Igor Sysoev9b25d692003-01-26 21:08:14 +0000258}
259
260
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000261void ngx_event_set_timer_delta(ngx_msec_t timer)
262{
263 ngx_int_t i;
264
265 for (i = 0; i < ngx_timer_queue_num; i++) {
266 ngx_timer_delta[i] = timer;
267 }
268}
269
270
271/* void ngx_event_expire_timers() */
Igor Sysoev404326f2003-01-24 06:20:47 +0000272void ngx_event_expire_timers(ngx_msec_t timer)
273{
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000274 ngx_int_t i;
275#if 0
Igor Sysoev404326f2003-01-24 06:20:47 +0000276 ngx_msec_t delta;
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000277#endif
Igor Sysoev404326f2003-01-24 06:20:47 +0000278 ngx_event_t *ev;
279
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000280#if 0
Igor Sysoev9d639522003-07-07 06:11:50 +0000281 ngx_expire_timers = 1;
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000282#endif
Igor Sysoev9d639522003-07-07 06:11:50 +0000283
Igor Sysoev9b25d692003-01-26 21:08:14 +0000284 for (i = 0; i < ngx_timer_queue_num; i++) {
Igor Sysoev404326f2003-01-24 06:20:47 +0000285
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000286#if 0
Igor Sysoev404326f2003-01-24 06:20:47 +0000287 delta = timer;
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000288#endif
Igor Sysoev404326f2003-01-24 06:20:47 +0000289
290 for ( ;; ) {
291 ev = ngx_timer_queue[i].timer_next;
292
293 if (ev == &ngx_timer_queue[i]) {
294 break;
295 }
296
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000297 if (ev->timer_delta > ngx_timer_delta[i]) {
298 ev->timer_delta -= ngx_timer_delta[i];
299 break;
300 }
301
302 ngx_timer_delta[i] -= ev->timer_delta;
303
304#if 0
Igor Sysoev404326f2003-01-24 06:20:47 +0000305 if (ev->timer_delta > delta) {
306 ev->timer_delta -= delta;
307 break;
308 }
309
310 delta -= ev->timer_delta;
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000311#endif
Igor Sysoev404326f2003-01-24 06:20:47 +0000312
313 ngx_del_timer(ev);
Igor Sysoeva9830112003-05-19 16:39:14 +0000314
Igor Sysoev6a7fd112003-04-17 17:59:35 +0000315 if (ev->delayed) {
316 ev->delayed = 0;
317 if (ev->ready == 0) {
318 continue;
319 }
320
321 } else {
322 ev->timedout = 1;
323 }
Igor Sysoev404326f2003-01-24 06:20:47 +0000324
Igor Sysoevd581fd52003-05-13 16:02:32 +0000325 ev->event_handler(ev);
Igor Sysoev404326f2003-01-24 06:20:47 +0000326 }
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000327
328 ngx_timer_delta[i] = 0;
Igor Sysoev404326f2003-01-24 06:20:47 +0000329 }
Igor Sysoev9d639522003-07-07 06:11:50 +0000330
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000331#if 0
Igor Sysoev9d639522003-07-07 06:11:50 +0000332 ngx_expire_timers = 0;
333
334 if (ngx_temp_timer_queue.timer_next == &ngx_temp_timer_queue) {
335 return;
336 }
337
338 timer = 0;
339
340 while (ngx_temp_timer_queue.timer_next != &ngx_temp_timer_queue) {
341 timer += ngx_temp_timer_queue.timer_next->timer_delta;
342 ev = ngx_temp_timer_queue.timer_next;
343
Igor Sysoev0a280a32003-10-12 16:49:16 +0000344#if (NGX_DEBUG_EVENT)
345 ngx_log_debug(ev->log, "process temp timer queue");
346#endif
347
Igor Sysoev9d639522003-07-07 06:11:50 +0000348 ngx_del_timer(ev);
349 ngx_add_timer(ev, timer);
350 }
Igor Sysoeva8fa0a62003-11-25 20:44:56 +0000351#endif
Igor Sysoev404326f2003-01-24 06:20:47 +0000352}
Igor Sysoevf5003d82003-12-04 14:53:00 +0000353
354
355#endif