blob: 1075586497d0a4f5f9154ec4865f195ad2c8182f [file] [log] [blame]
Igor Sysoev6b7cfab2003-01-21 17:36:01 +00001
Igor Sysoevd90282d2004-09-28 08:34:51 +00002/*
Igor Sysoevff8da912004-09-29 16:00:49 +00003 * Copyright (C) Igor Sysoev
Maxim Konovalovf8d59e32012-01-18 15:07:43 +00004 * Copyright (C) Nginx, Inc.
Igor Sysoevd90282d2004-09-28 08:34:51 +00005 */
6
7
Igor Sysoevfcce8d52003-01-23 18:47:54 +00008#include <ngx_config.h>
Igor Sysoevfcce8d52003-01-23 18:47:54 +00009#include <ngx_core.h>
Igor Sysoevfcce8d52003-01-23 18:47:54 +000010#include <ngx_event.h>
11
Igor Sysoevfcce8d52003-01-23 18:47:54 +000012
Igor Sysoevb54698b2004-02-23 20:57:12 +000013#if (NGX_THREADS)
Igor Sysoevf2334412004-02-25 20:16:15 +000014ngx_mutex_t *ngx_event_timer_mutex;
Igor Sysoevb54698b2004-02-23 20:57:12 +000015#endif
16
Igor Sysoevdc867cd2003-12-14 20:10:27 +000017
Igor Sysoev1bfa7bc2005-10-10 12:59:41 +000018ngx_thread_volatile ngx_rbtree_t ngx_event_timer_rbtree;
19static ngx_rbtree_node_t ngx_event_timer_sentinel;
Igor Sysoevf5003d82003-12-04 14:53:00 +000020
Igor Sysoev6a23cf02007-01-12 19:26:38 +000021/*
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 */
Igor Sysoevf5003d82003-12-04 14:53:00 +000026
Igor Sysoevd039a2e2005-02-22 14:40:13 +000027ngx_int_t
28ngx_event_timer_init(ngx_log_t *log)
Igor Sysoevf5003d82003-12-04 14:53:00 +000029{
Igor Sysoev7912e4b2007-12-17 08:52:00 +000030 ngx_rbtree_init(&ngx_event_timer_rbtree, &ngx_event_timer_sentinel,
31 ngx_rbtree_insert_timer_value);
Igor Sysoev1bfa7bc2005-10-10 12:59:41 +000032
Igor Sysoevd94049b2004-02-29 21:03:02 +000033#if (NGX_THREADS)
Igor Sysoev1bfa7bc2005-10-10 12:59:41 +000034
35 if (ngx_event_timer_mutex) {
Igor Sysoevf2334412004-02-25 20:16:15 +000036 ngx_event_timer_mutex->log = log;
37 return NGX_OK;
Igor Sysoev2b58fbf2003-12-09 15:08:11 +000038 }
39
Igor Sysoevc1571722005-03-19 12:38:37 +000040 ngx_event_timer_mutex = ngx_mutex_init(log, 0);
41 if (ngx_event_timer_mutex == NULL) {
Igor Sysoevf2334412004-02-25 20:16:15 +000042 return NGX_ERROR;
43 }
Igor Sysoev1bfa7bc2005-10-10 12:59:41 +000044
Igor Sysoevd94049b2004-02-29 21:03:02 +000045#endif
Igor Sysoevf2334412004-02-25 20:16:15 +000046
47 return NGX_OK;
Igor Sysoevf5003d82003-12-04 14:53:00 +000048}
49
50
Igor Sysoevd039a2e2005-02-22 14:40:13 +000051ngx_msec_t
52ngx_event_find_timer(void)
Igor Sysoevf5003d82003-12-04 14:53:00 +000053{
Igor Sysoev78452232005-10-12 13:50:36 +000054 ngx_msec_int_t timer;
55 ngx_rbtree_node_t *node, *root, *sentinel;
Igor Sysoevf5003d82003-12-04 14:53:00 +000056
Igor Sysoev1bfa7bc2005-10-10 12:59:41 +000057 if (ngx_event_timer_rbtree.root == &ngx_event_timer_sentinel) {
Igor Sysoevcccc5522004-04-14 20:34:05 +000058 return NGX_TIMER_INFINITE;
Igor Sysoev1cd1e272003-12-19 12:45:27 +000059 }
60
Igor Sysoevc2068d02005-10-19 12:33:58 +000061 ngx_mutex_lock(ngx_event_timer_mutex);
Igor Sysoevf2334412004-02-25 20:16:15 +000062
Igor Sysoev1bfa7bc2005-10-10 12:59:41 +000063 root = ngx_event_timer_rbtree.root;
64 sentinel = ngx_event_timer_rbtree.sentinel;
65
66 node = ngx_rbtree_min(root, sentinel);
Igor Sysoevf5003d82003-12-04 14:53:00 +000067
Igor Sysoevf2334412004-02-25 20:16:15 +000068 ngx_mutex_unlock(ngx_event_timer_mutex);
Igor Sysoevf2334412004-02-25 20:16:15 +000069
Maxim Douninbaa239c2012-04-06 23:46:09 +000070 timer = (ngx_msec_int_t) (node->key - ngx_current_msec);
Igor Sysoevb3968b32004-04-14 17:44:28 +000071
Igor Sysoev1bfa7bc2005-10-10 12:59:41 +000072 return (ngx_msec_t) (timer > 0 ? timer : 0);
Igor Sysoevf5003d82003-12-04 14:53:00 +000073}
74
75
Igor Sysoevd039a2e2005-02-22 14:40:13 +000076void
Igor Sysoev208eed22005-10-07 13:30:52 +000077ngx_event_expire_timers(void)
Igor Sysoevf5003d82003-12-04 14:53:00 +000078{
Igor Sysoev1bfa7bc2005-10-10 12:59:41 +000079 ngx_event_t *ev;
80 ngx_rbtree_node_t *node, *root, *sentinel;
81
82 sentinel = ngx_event_timer_rbtree.sentinel;
Igor Sysoevf5003d82003-12-04 14:53:00 +000083
84 for ( ;; ) {
Igor Sysoevf5003d82003-12-04 14:53:00 +000085
Igor Sysoevc2068d02005-10-19 12:33:58 +000086 ngx_mutex_lock(ngx_event_timer_mutex);
Igor Sysoevf2334412004-02-25 20:16:15 +000087
Igor Sysoev1bfa7bc2005-10-10 12:59:41 +000088 root = ngx_event_timer_rbtree.root;
89
90 if (root == sentinel) {
91 return;
92 }
93
94 node = ngx_rbtree_min(root, sentinel);
Igor Sysoev1cd1e272003-12-19 12:45:27 +000095
Igor Sysoev208eed22005-10-07 13:30:52 +000096 /* node->key <= ngx_current_time */
97
Maxim Douninbaa239c2012-04-06 23:46:09 +000098 if ((ngx_msec_int_t) (node->key - ngx_current_msec) <= 0) {
Igor Sysoev1bfa7bc2005-10-10 12:59:41 +000099 ev = (ngx_event_t *) ((char *) node - offsetof(ngx_event_t, timer));
Igor Sysoevf5003d82003-12-04 14:53:00 +0000100
Igor Sysoevb14b9102004-06-28 16:05:02 +0000101 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
Igor Sysoev208eed22005-10-07 13:30:52 +0000102 "event timer del: %d: %M",
Igor Sysoev1bfa7bc2005-10-10 12:59:41 +0000103 ngx_event_ident(ev->data), ev->timer.key);
Igor Sysoevb14b9102004-06-28 16:05:02 +0000104
Igor Sysoev1bfa7bc2005-10-10 12:59:41 +0000105 ngx_rbtree_delete(&ngx_event_timer_rbtree, &ev->timer);
Igor Sysoevb14b9102004-06-28 16:05:02 +0000106
107 ngx_mutex_unlock(ngx_event_timer_mutex);
108
109#if (NGX_DEBUG)
Igor Sysoev1bfa7bc2005-10-10 12:59:41 +0000110 ev->timer.left = NULL;
111 ev->timer.right = NULL;
112 ev->timer.parent = NULL;
Igor Sysoevb14b9102004-06-28 16:05:02 +0000113#endif
114
115 ev->timer_set = 0;
Igor Sysoevf5003d82003-12-04 14:53:00 +0000116
Igor Sysoev46cd7c22004-07-02 05:47:00 +0000117 ev->timedout = 1;
118
Igor Sysoev899b44e2005-05-12 14:58:06 +0000119 ev->handler(ev);
Igor Sysoev46cd7c22004-07-02 05:47:00 +0000120
Igor Sysoevf5003d82003-12-04 14:53:00 +0000121 continue;
122 }
Igor Sysoev46cd7c22004-07-02 05:47:00 +0000123
Igor Sysoevf5003d82003-12-04 14:53:00 +0000124 break;
125 }
Igor Sysoevb14b9102004-06-28 16:05:02 +0000126
127 ngx_mutex_unlock(ngx_event_timer_mutex);
Igor Sysoevf5003d82003-12-04 14:53:00 +0000128}