comparison src/event/ngx_event_timer.c @ 0:f0b350454894 NGINX_0_1_0

nginx 0.1.0 *) The first public version.
author Igor Sysoev <http://sysoev.ru>
date Mon, 04 Oct 2004 00:00:00 +0400
parents
children 46833bd150cb
comparison
equal deleted inserted replaced
-1:000000000000 0:f0b350454894
1
2 /*
3 * Copyright (C) Igor Sysoev
4 */
5
6
7 #include <ngx_config.h>
8 #include <ngx_core.h>
9 #include <ngx_event.h>
10
11
12 #if (NGX_THREADS)
13 ngx_mutex_t *ngx_event_timer_mutex;
14 #endif
15
16
17 ngx_thread_volatile ngx_rbtree_t *ngx_event_timer_rbtree;
18 ngx_rbtree_t ngx_event_timer_sentinel;
19
20
21 ngx_int_t ngx_event_timer_init(ngx_log_t *log)
22 {
23 if (ngx_event_timer_rbtree) {
24 #if (NGX_THREADS)
25 ngx_event_timer_mutex->log = log;
26 #endif
27 return NGX_OK;
28 }
29
30 ngx_event_timer_rbtree = &ngx_event_timer_sentinel;
31
32 #if (NGX_THREADS)
33 if (!(ngx_event_timer_mutex = ngx_mutex_init(log, 0))) {
34 return NGX_ERROR;
35 }
36 #endif
37
38 return NGX_OK;
39 }
40
41
42 ngx_msec_t ngx_event_find_timer(void)
43 {
44 ngx_msec_t timer;
45 ngx_rbtree_t *node;
46
47 if (ngx_event_timer_rbtree == &ngx_event_timer_sentinel) {
48 return NGX_TIMER_INFINITE;
49 }
50
51 if (ngx_mutex_lock(ngx_event_timer_mutex) == NGX_ERROR) {
52 return NGX_TIMER_ERROR;
53 }
54
55 node = ngx_rbtree_min((ngx_rbtree_t *) ngx_event_timer_rbtree,
56 &ngx_event_timer_sentinel);
57
58 ngx_mutex_unlock(ngx_event_timer_mutex);
59
60 timer = (ngx_msec_t)
61 (node->key * NGX_TIMER_RESOLUTION -
62 ngx_elapsed_msec / NGX_TIMER_RESOLUTION * NGX_TIMER_RESOLUTION);
63 #if 0
64 (node->key * NGX_TIMER_RESOLUTION - ngx_elapsed_msec);
65 #endif
66
67 return timer > 0 ? timer: 0 ;
68 }
69
70
71 void ngx_event_expire_timers(ngx_msec_t timer)
72 {
73 ngx_event_t *ev;
74 ngx_rbtree_t *node;
75
76 if (timer < 0) {
77 /* avoid the endless loop if the time goes backward for some reason */
78 timer = 0;
79 }
80
81 for ( ;; ) {
82
83 if (ngx_event_timer_rbtree == &ngx_event_timer_sentinel) {
84 return;
85 }
86
87 if (ngx_mutex_lock(ngx_event_timer_mutex) == NGX_ERROR) {
88 return;
89 }
90
91 node = ngx_rbtree_min((ngx_rbtree_t *) ngx_event_timer_rbtree,
92 &ngx_event_timer_sentinel);
93
94 if (node->key <= (ngx_msec_t)
95 (ngx_old_elapsed_msec + timer) / NGX_TIMER_RESOLUTION)
96 {
97 ev = (ngx_event_t *)
98 ((char *) node - offsetof(ngx_event_t, rbtree_key));
99
100 #if (NGX_THREADS)
101
102 if (ngx_threaded && ngx_trylock(ev->lock) == 0) {
103
104 /*
105 * We can not change the timer of the event that is been
106 * handling by another thread. And we can not easy walk
107 * the rbtree to find a next expired timer so we exit the loop.
108 * However it should be rare case when the event that is
109 * been handling has expired timer.
110 */
111
112 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ev->log, 0,
113 "event " PTR_FMT " is busy in expire timers",
114 ev);
115 break;
116 }
117 #endif
118
119 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
120 "event timer del: %d: %d",
121 ngx_event_ident(ev->data), ev->rbtree_key);
122
123 ngx_rbtree_delete((ngx_rbtree_t **) &ngx_event_timer_rbtree,
124 &ngx_event_timer_sentinel,
125 (ngx_rbtree_t *) &ev->rbtree_key);
126
127 ngx_mutex_unlock(ngx_event_timer_mutex);
128
129 #if (NGX_DEBUG)
130 ev->rbtree_left = NULL;
131 ev->rbtree_right = NULL;
132 ev->rbtree_parent = NULL;
133 #endif
134
135 ev->timer_set = 0;
136
137 #if (NGX_THREADS)
138 if (ngx_threaded) {
139 if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) {
140 return;
141 }
142
143 ev->posted_timedout = 1;
144 ngx_post_event(ev);
145
146 ngx_mutex_unlock(ngx_posted_events_mutex);
147
148 ngx_unlock(ev->lock);
149
150 continue;
151 }
152 #endif
153
154 ev->timedout = 1;
155
156 ev->event_handler(ev);
157
158 continue;
159 }
160
161 break;
162 }
163
164 ngx_mutex_unlock(ngx_event_timer_mutex);
165 }