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>