~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Nginx/event/ngx_event_timer.c

Version: ~ [ nginx-0.8.20 ] ~ [ nginx-0.7.62 ] ~ [ nginx-0.6.39 ] ~

  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 static ngx_rbtree_node_t          ngx_event_timer_sentinel;
 19 
 20 /*
 21  * the event timer rbtree may contain the duplicate keys, however,
 22  * it should not be a problem, because we use the rbtree to find
 23  * a minimum timer value only
 24  */
 25 
 26 ngx_int_t
 27 ngx_event_timer_init(ngx_log_t *log)
 28 {
 29     ngx_rbtree_init(&ngx_event_timer_rbtree, &ngx_event_timer_sentinel,
 30                     ngx_rbtree_insert_timer_value);
 31 
 32 #if (NGX_THREADS)
 33 
 34     if (ngx_event_timer_mutex) {
 35         ngx_event_timer_mutex->log = log;
 36         return NGX_OK;
 37     }
 38 
 39     ngx_event_timer_mutex = ngx_mutex_init(log, 0);
 40     if (ngx_event_timer_mutex == NULL) {
 41         return NGX_ERROR;
 42     }
 43 
 44 #endif
 45 
 46     return NGX_OK;
 47 }
 48 
 49 
 50 ngx_msec_t
 51 ngx_event_find_timer(void)
 52 {
 53     ngx_msec_int_t      timer;
 54     ngx_rbtree_node_t  *node, *root, *sentinel;
 55 
 56     if (ngx_event_timer_rbtree.root == &ngx_event_timer_sentinel) {
 57         return NGX_TIMER_INFINITE;
 58     }
 59 
 60     ngx_mutex_lock(ngx_event_timer_mutex);
 61 
 62     root = ngx_event_timer_rbtree.root;
 63     sentinel = ngx_event_timer_rbtree.sentinel;
 64 
 65     node = ngx_rbtree_min(root, sentinel);
 66 
 67     ngx_mutex_unlock(ngx_event_timer_mutex);
 68 
 69     timer = (ngx_msec_int_t) node->key - (ngx_msec_int_t) ngx_current_msec;
 70 
 71     return (ngx_msec_t) (timer > 0 ? timer : 0);
 72 }
 73 
 74 
 75 void
 76 ngx_event_expire_timers(void)
 77 {
 78     ngx_event_t        *ev;
 79     ngx_rbtree_node_t  *node, *root, *sentinel;
 80 
 81     sentinel = ngx_event_timer_rbtree.sentinel;
 82 
 83     for ( ;; ) {
 84 
 85         ngx_mutex_lock(ngx_event_timer_mutex);
 86 
 87         root = ngx_event_timer_rbtree.root;
 88 
 89         if (root == sentinel) {
 90             return;
 91         }
 92 
 93         node = ngx_rbtree_min(root, sentinel);
 94 
 95         /* node->key <= ngx_current_time */
 96 
 97         if ((ngx_msec_int_t) node->key - (ngx_msec_int_t) ngx_current_msec <= 0)
 98         {
 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 can not change the timer of the event that is been
107                  * handling by another thread.  And we can not easy walk
108                  * the rbtree to find a next expired timer so we exit the loop.
109                  * However it should be rare case when the event that is
110                  * been handling has 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 }
159 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.