Annotation of embedaddon/nginx/src/event/ngx_event_timer.c, revision 1.1.1.1
1.1 misho 1:
2: /*
3: * Copyright (C) Igor Sysoev
4: * Copyright (C) Nginx, Inc.
5: */
6:
7:
8: #include <ngx_config.h>
9: #include <ngx_core.h>
10: #include <ngx_event.h>
11:
12:
13: #if (NGX_THREADS)
14: ngx_mutex_t *ngx_event_timer_mutex;
15: #endif
16:
17:
18: ngx_thread_volatile ngx_rbtree_t ngx_event_timer_rbtree;
19: static ngx_rbtree_node_t ngx_event_timer_sentinel;
20:
21: /*
22: * the event timer rbtree may contain the duplicate keys, however,
23: * it should not be a problem, because we use the rbtree to find
24: * a minimum timer value only
25: */
26:
27: ngx_int_t
28: ngx_event_timer_init(ngx_log_t *log)
29: {
30: ngx_rbtree_init(&ngx_event_timer_rbtree, &ngx_event_timer_sentinel,
31: ngx_rbtree_insert_timer_value);
32:
33: #if (NGX_THREADS)
34:
35: if (ngx_event_timer_mutex) {
36: ngx_event_timer_mutex->log = log;
37: return NGX_OK;
38: }
39:
40: ngx_event_timer_mutex = ngx_mutex_init(log, 0);
41: if (ngx_event_timer_mutex == NULL) {
42: return NGX_ERROR;
43: }
44:
45: #endif
46:
47: return NGX_OK;
48: }
49:
50:
51: ngx_msec_t
52: ngx_event_find_timer(void)
53: {
54: ngx_msec_int_t timer;
55: ngx_rbtree_node_t *node, *root, *sentinel;
56:
57: if (ngx_event_timer_rbtree.root == &ngx_event_timer_sentinel) {
58: return NGX_TIMER_INFINITE;
59: }
60:
61: ngx_mutex_lock(ngx_event_timer_mutex);
62:
63: root = ngx_event_timer_rbtree.root;
64: sentinel = ngx_event_timer_rbtree.sentinel;
65:
66: node = ngx_rbtree_min(root, sentinel);
67:
68: ngx_mutex_unlock(ngx_event_timer_mutex);
69:
70: timer = (ngx_msec_int_t) (node->key - ngx_current_msec);
71:
72: return (ngx_msec_t) (timer > 0 ? timer : 0);
73: }
74:
75:
76: void
77: ngx_event_expire_timers(void)
78: {
79: ngx_event_t *ev;
80: ngx_rbtree_node_t *node, *root, *sentinel;
81:
82: sentinel = ngx_event_timer_rbtree.sentinel;
83:
84: for ( ;; ) {
85:
86: ngx_mutex_lock(ngx_event_timer_mutex);
87:
88: root = ngx_event_timer_rbtree.root;
89:
90: if (root == sentinel) {
91: return;
92: }
93:
94: node = ngx_rbtree_min(root, sentinel);
95:
96: /* node->key <= ngx_current_time */
97:
98: if ((ngx_msec_int_t) (node->key - ngx_current_msec) <= 0) {
99: ev = (ngx_event_t *) ((char *) node - offsetof(ngx_event_t, timer));
100:
101: #if (NGX_THREADS)
102:
103: if (ngx_threaded && ngx_trylock(ev->lock) == 0) {
104:
105: /*
106: * We cannot change the timer of the event that is being
107: * handled by another thread. And we cannot easy walk
108: * the rbtree to find next expired timer so we exit the loop.
109: * However, it should be a rare case when the event that is
110: * being handled has an expired timer.
111: */
112:
113: ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ev->log, 0,
114: "event %p is busy in expire timers", ev);
115: break;
116: }
117: #endif
118:
119: ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
120: "event timer del: %d: %M",
121: ngx_event_ident(ev->data), ev->timer.key);
122:
123: ngx_rbtree_delete(&ngx_event_timer_rbtree, &ev->timer);
124:
125: ngx_mutex_unlock(ngx_event_timer_mutex);
126:
127: #if (NGX_DEBUG)
128: ev->timer.left = NULL;
129: ev->timer.right = NULL;
130: ev->timer.parent = NULL;
131: #endif
132:
133: ev->timer_set = 0;
134:
135: #if (NGX_THREADS)
136: if (ngx_threaded) {
137: ev->posted_timedout = 1;
138:
139: ngx_post_event(ev, &ngx_posted_events);
140:
141: ngx_unlock(ev->lock);
142:
143: continue;
144: }
145: #endif
146:
147: ev->timedout = 1;
148:
149: ev->handler(ev);
150:
151: continue;
152: }
153:
154: break;
155: }
156:
157: ngx_mutex_unlock(ngx_event_timer_mutex);
158: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>