Annotation of embedaddon/nginx/src/event/ngx_event_timer.c, revision 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>