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>