blob: a3d4d808dcefa6fbef466aa235b5295ba460a4ca [file] [log] [blame]
Igor Sysoev6b7cfab2003-01-21 17:36:01 +00001
Igor Sysoevfcce8d52003-01-23 18:47:54 +00002#include <ngx_config.h>
Igor Sysoevfcce8d52003-01-23 18:47:54 +00003#include <ngx_core.h>
Igor Sysoevfcce8d52003-01-23 18:47:54 +00004#include <ngx_event.h>
5
Igor Sysoevfcce8d52003-01-23 18:47:54 +00006
Igor Sysoevb54698b2004-02-23 20:57:12 +00007#if (NGX_THREADS)
Igor Sysoevf2334412004-02-25 20:16:15 +00008ngx_mutex_t *ngx_event_timer_mutex;
Igor Sysoevb54698b2004-02-23 20:57:12 +00009#endif
10
Igor Sysoevdc867cd2003-12-14 20:10:27 +000011
Igor Sysoevea0b1d92004-03-02 15:40:59 +000012ngx_thread_volatile ngx_rbtree_t *ngx_event_timer_rbtree;
13ngx_rbtree_t ngx_event_timer_sentinel;
Igor Sysoevf5003d82003-12-04 14:53:00 +000014
15
Igor Sysoevf2334412004-02-25 20:16:15 +000016ngx_int_t ngx_event_timer_init(ngx_log_t *log)
Igor Sysoevf5003d82003-12-04 14:53:00 +000017{
Igor Sysoev3c3ca172004-01-05 20:55:48 +000018 if (ngx_event_timer_rbtree) {
Igor Sysoevd94049b2004-02-29 21:03:02 +000019#if (NGX_THREADS)
Igor Sysoevf2334412004-02-25 20:16:15 +000020 ngx_event_timer_mutex->log = log;
Igor Sysoevd94049b2004-02-29 21:03:02 +000021#endif
Igor Sysoevf2334412004-02-25 20:16:15 +000022 return NGX_OK;
Igor Sysoev2b58fbf2003-12-09 15:08:11 +000023 }
24
Igor Sysoev62260f22003-12-05 17:07:27 +000025 ngx_event_timer_rbtree = &ngx_event_timer_sentinel;
Igor Sysoevf2334412004-02-25 20:16:15 +000026
Igor Sysoevd94049b2004-02-29 21:03:02 +000027#if (NGX_THREADS)
Igor Sysoevf2334412004-02-25 20:16:15 +000028 if (!(ngx_event_timer_mutex = ngx_mutex_init(log, 0))) {
29 return NGX_ERROR;
30 }
Igor Sysoevd94049b2004-02-29 21:03:02 +000031#endif
Igor Sysoevf2334412004-02-25 20:16:15 +000032
33 return NGX_OK;
Igor Sysoevf5003d82003-12-04 14:53:00 +000034}
35
36
Igor Sysoevfaca1192003-12-05 07:11:46 +000037ngx_msec_t ngx_event_find_timer(void)
Igor Sysoevf5003d82003-12-04 14:53:00 +000038{
Igor Sysoevb3968b32004-04-14 17:44:28 +000039 ngx_msec_t timer;
Igor Sysoevf5003d82003-12-04 14:53:00 +000040 ngx_rbtree_t *node;
41
Igor Sysoev1cd1e272003-12-19 12:45:27 +000042 if (ngx_event_timer_rbtree == &ngx_event_timer_sentinel) {
Igor Sysoevcccc5522004-04-14 20:34:05 +000043 return NGX_TIMER_INFINITE;
Igor Sysoev1cd1e272003-12-19 12:45:27 +000044 }
45
Igor Sysoevf2334412004-02-25 20:16:15 +000046 if (ngx_mutex_lock(ngx_event_timer_mutex) == NGX_ERROR) {
47 return NGX_TIMER_ERROR;
48 }
Igor Sysoevf2334412004-02-25 20:16:15 +000049
Igor Sysoevd94049b2004-02-29 21:03:02 +000050 node = ngx_rbtree_min((ngx_rbtree_t *) ngx_event_timer_rbtree,
51 &ngx_event_timer_sentinel);
Igor Sysoevf5003d82003-12-04 14:53:00 +000052
Igor Sysoevf2334412004-02-25 20:16:15 +000053 ngx_mutex_unlock(ngx_event_timer_mutex);
Igor Sysoevf2334412004-02-25 20:16:15 +000054
Igor Sysoevb3968b32004-04-14 17:44:28 +000055 timer = (ngx_msec_t)
Igor Sysoevdc867cd2003-12-14 20:10:27 +000056 (node->key * NGX_TIMER_RESOLUTION -
57 ngx_elapsed_msec / NGX_TIMER_RESOLUTION * NGX_TIMER_RESOLUTION);
58#if 0
Igor Sysoevfaca1192003-12-05 07:11:46 +000059 (node->key * NGX_TIMER_RESOLUTION - ngx_elapsed_msec);
Igor Sysoevdc867cd2003-12-14 20:10:27 +000060#endif
Igor Sysoevb3968b32004-04-14 17:44:28 +000061
Igor Sysoevcccc5522004-04-14 20:34:05 +000062 return timer > 0 ? timer: 0 ;
Igor Sysoevf5003d82003-12-04 14:53:00 +000063}
64
65
66void ngx_event_expire_timers(ngx_msec_t timer)
67{
68 ngx_event_t *ev;
69 ngx_rbtree_t *node;
70
71 for ( ;; ) {
Igor Sysoevf5003d82003-12-04 14:53:00 +000072
Igor Sysoev1cd1e272003-12-19 12:45:27 +000073 if (ngx_event_timer_rbtree == &ngx_event_timer_sentinel) {
Igor Sysoevf5003d82003-12-04 14:53:00 +000074 break;
75 }
76
Igor Sysoevf2334412004-02-25 20:16:15 +000077 if (ngx_mutex_lock(ngx_event_timer_mutex) == NGX_ERROR) {
78 return;
79 }
Igor Sysoevf2334412004-02-25 20:16:15 +000080
Igor Sysoevd94049b2004-02-29 21:03:02 +000081 node = ngx_rbtree_min((ngx_rbtree_t *) ngx_event_timer_rbtree,
Igor Sysoev1cd1e272003-12-19 12:45:27 +000082 &ngx_event_timer_sentinel);
83
Igor Sysoevf2334412004-02-25 20:16:15 +000084 ngx_mutex_unlock(ngx_event_timer_mutex);
Igor Sysoevf2334412004-02-25 20:16:15 +000085
Igor Sysoevcccc5522004-04-14 20:34:05 +000086 if (node->key <= (ngx_msec_t)
Igor Sysoev62260f22003-12-05 17:07:27 +000087 (ngx_old_elapsed_msec + timer) / NGX_TIMER_RESOLUTION)
Igor Sysoevf5003d82003-12-04 14:53:00 +000088 {
89 ev = (ngx_event_t *)
Igor Sysoevfaca1192003-12-05 07:11:46 +000090 ((char *) node - offsetof(ngx_event_t, rbtree_key));
Igor Sysoevf5003d82003-12-04 14:53:00 +000091
92 ngx_del_timer(ev);
93
94 if (ev->delayed) {
95 ev->delayed = 0;
96 if (ev->ready == 0) {
97 continue;
98 }
99
100 } else {
101 ev->timedout = 1;
102 }
103
Igor Sysoev9a864bd2004-04-04 20:32:09 +0000104 if (ngx_threaded) {
105 if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) {
106 return;
107 }
108
109 ngx_post_event(ev);
110
111 ngx_mutex_unlock(ngx_posted_events_mutex);
112 continue;
113 }
Igor Sysoevf2334412004-02-25 20:16:15 +0000114
Igor Sysoevf5003d82003-12-04 14:53:00 +0000115 ev->event_handler(ev);
116 continue;
117 }
118
119 break;
120 }
121}