fix extension
[nginx.git] / nginx / src / event / ngx_event_posted.c
1
2 /*
3  * Copyright (C) Igor Sysoev
4  */
5
6
7 #include <ngx_config.h>
8 #include <ngx_core.h>
9 #include <ngx_event.h>
10
11
12 ngx_thread_volatile ngx_event_t  *ngx_posted_accept_events;
13 ngx_thread_volatile ngx_event_t  *ngx_posted_events;
14
15 #if (NGX_THREADS)
16 ngx_mutex_t                      *ngx_posted_events_mutex;
17 #endif
18
19
20 void
21 ngx_event_process_posted(ngx_cycle_t *cycle,
22     ngx_thread_volatile ngx_event_t **posted)
23 {
24     ngx_event_t  *ev;
25
26     for ( ;; ) {
27
28         ev = (ngx_event_t *) *posted;
29
30         ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
31                       "posted event %p", ev);
32
33         if (ev == NULL) {
34             return;
35         }
36
37         ngx_delete_posted_event(ev);
38
39         ev->handler(ev);
40     }
41 }
42
43
44 #if (NGX_THREADS) && !(NGX_WIN32)
45
46 void
47 ngx_wakeup_worker_thread(ngx_cycle_t *cycle)
48 {
49     ngx_int_t     i;
50 #if 0
51     ngx_uint_t    busy;
52     ngx_event_t  *ev;
53
54     busy = 1;
55
56     if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) {
57         return;
58     }
59
60     for (ev = (ngx_event_t *) ngx_posted_events; ev; ev = ev->next) {
61         if (*(ev->lock) == 0) {
62             busy = 0;
63             break;
64         }
65     }
66
67     ngx_mutex_unlock(ngx_posted_events_mutex);
68
69     if (busy) {
70         return;
71     }
72 #endif
73
74     for (i = 0; i < ngx_threads_n; i++) {
75         if (ngx_threads[i].state == NGX_THREAD_FREE) {
76             ngx_cond_signal(ngx_threads[i].cv);
77             return;
78         }
79     }
80 }
81
82
83 ngx_int_t
84 ngx_event_thread_process_posted(ngx_cycle_t *cycle)
85 {
86     ngx_event_t  *ev;
87
88     for ( ;; ) {
89
90         ev = (ngx_event_t *) ngx_posted_events;
91
92         for ( ;; ) {
93
94             ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
95                           "posted event %p", ev);
96
97             if (ev == NULL) {
98                 return NGX_OK;
99             }
100
101             if (ngx_trylock(ev->lock) == 0) {
102
103                 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
104                                "posted event %p is busy", ev);
105
106                 ev = ev->next;
107                 continue;
108             }
109
110             if (ev->lock != ev->own_lock) {
111                 if (*(ev->own_lock)) {
112                     ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
113                              "the own lock of the posted event %p is busy", ev);
114                     ngx_unlock(ev->lock);
115                     ev = ev->next;
116                     continue;
117                 }
118                 *(ev->own_lock) = 1;
119             }
120
121             ngx_delete_posted_event(ev);
122
123             ev->locked = 1;
124
125             ev->ready |= ev->posted_ready;
126             ev->timedout |= ev->posted_timedout;
127             ev->pending_eof |= ev->posted_eof;
128 #if (NGX_HAVE_KQUEUE)
129             ev->kq_errno |= ev->posted_errno;
130 #endif
131             if (ev->posted_available) {
132                 ev->available = ev->posted_available;
133             }
134
135             ev->posted_ready = 0;
136             ev->posted_timedout = 0;
137             ev->posted_eof = 0;
138 #if (NGX_HAVE_KQUEUE)
139             ev->posted_errno = 0;
140 #endif
141             ev->posted_available = 0;
142
143             ngx_mutex_unlock(ngx_posted_events_mutex);
144
145             ev->handler(ev);
146
147             ngx_mutex_lock(ngx_posted_events_mutex);
148
149             if (ev->locked) {
150                 ngx_unlock(ev->lock);
151
152                 if (ev->lock != ev->own_lock) {
153                     ngx_unlock(ev->own_lock);
154                 }
155             }
156
157             ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
158                            "posted event %p is done", ev);
159
160             break;
161         }
162     }
163 }
164
165 #else
166
167 void
168 ngx_wakeup_worker_thread(ngx_cycle_t *cycle)
169 {
170 }
171
172 #endif