Mercurial > hg > nginx-quic
comparison src/event/modules/ngx_select_module.c @ 8:708f8bb772ec
nginx-0.0.1-2002-09-02-18:48:24 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Mon, 02 Sep 2002 14:48:24 +0000 |
parents | b5481d6fbbd4 |
children | 2aba961a1d34 |
comparison
equal
deleted
inserted
replaced
7:b5481d6fbbd4 | 8:708f8bb772ec |
---|---|
1 | 1 |
2 #include <ngx_config.h> | 2 #include <ngx_config.h> |
3 #include <ngx_core.h> | |
3 #include <ngx_types.h> | 4 #include <ngx_types.h> |
4 #include <ngx_log.h> | 5 #include <ngx_log.h> |
5 #include <ngx_time.h> | 6 #include <ngx_time.h> |
6 #include <ngx_connection.h> | 7 #include <ngx_connection.h> |
7 #include <ngx_event.h> | 8 #include <ngx_event.h> |
8 #include <ngx_select_module.h> | 9 #include <ngx_select_module.h> |
9 | 10 |
10 static fd_set master_read_fds; | 11 static fd_set master_read_fd_set; |
11 static fd_set master_write_fds; | 12 static fd_set master_write_fd_set; |
12 static fd_set work_read_fds; | 13 static fd_set work_read_fd_set; |
13 static fd_set work_write_fds; | 14 static fd_set work_write_fd_set; |
14 | 15 |
15 #if (WIN32) | 16 #if (WIN32) |
16 static int max_read; | 17 static int max_read; |
17 static int max_write; | 18 static int max_write; |
18 #else | 19 #else |
21 | 22 |
22 static ngx_event_t event_queue; | 23 static ngx_event_t event_queue; |
23 static ngx_event_t timer_queue; | 24 static ngx_event_t timer_queue; |
24 | 25 |
25 | 26 |
26 static void ngx_add_timer_core(ngx_event_t *ev, u_int timer); | |
27 | |
28 static fd_set *ngx_select_get_fd_set(ngx_socket_t fd, int event, | 27 static fd_set *ngx_select_get_fd_set(ngx_socket_t fd, int event, |
29 ngx_log_t *log); | 28 ngx_log_t *log); |
30 | 29 |
31 void ngx_select_init(int max_connections, ngx_log_t *log) | 30 void ngx_select_init(int max_connections, ngx_log_t *log) |
32 { | 31 { |
40 "supported by select() is %d", FD_SETSIZE - 1); | 39 "supported by select() is %d", FD_SETSIZE - 1); |
41 #endif | 40 #endif |
42 exit(1); | 41 exit(1); |
43 } | 42 } |
44 | 43 |
45 FD_ZERO(&master_read_fds); | 44 FD_ZERO(&master_read_fd_set); |
46 FD_ZERO(&master_write_fds); | 45 FD_ZERO(&master_write_fd_set); |
47 | 46 |
48 event_queue.prev = &event_queue; | 47 event_queue.prev = &event_queue; |
49 event_queue.next = &event_queue; | 48 event_queue.next = &event_queue; |
50 | 49 |
51 timer_queue.timer_prev = &timer_queue; | 50 timer_queue.timer_prev = &timer_queue; |
52 timer_queue.timer_next = &timer_queue; | 51 timer_queue.timer_next = &timer_queue; |
53 | 52 |
54 ngx_event_actions.add = ngx_select_add_event; | 53 ngx_event_actions.add = ngx_select_add_event; |
55 ngx_event_actions.del = ngx_select_del_event; | 54 ngx_event_actions.del = ngx_select_del_event; |
55 ngx_event_actions.timer = ngx_select_add_timer; | |
56 ngx_event_actions.process = ngx_select_process_events; | 56 ngx_event_actions.process = ngx_select_process_events; |
57 | 57 |
58 #if (WIN32) | 58 #if (WIN32) |
59 max_read = max_write = 0; | 59 max_read = max_write = 0; |
60 #else | 60 #else |
62 #endif | 62 #endif |
63 } | 63 } |
64 | 64 |
65 int ngx_select_add_event(ngx_event_t *ev, int event, u_int flags) | 65 int ngx_select_add_event(ngx_event_t *ev, int event, u_int flags) |
66 { | 66 { |
67 fd_set *fds; | 67 ngx_connection_t *c; |
68 ngx_connection_t *cn = (ngx_connection_t *) ev->data; | 68 |
69 | 69 c = (ngx_connection_t *) ev->data; |
70 if (event == NGX_TIMER_EVENT) { | 70 |
71 ngx_add_timer_core(ev, flags); | 71 ngx_log_debug(ev->log, "select fd:%d event:%d" _ c->fd _ event); |
72 return 0; | 72 |
73 } | 73 #if (WIN32) |
74 | 74 if ((event == NGX_READ_EVENT) && (max_read >= FD_SETSIZE) |
75 ngx_assert((flags != NGX_ONESHOT_EVENT), return -1, ev->log, | 75 || (event == NGX_WRITE_EVENT) && (max_write >= FD_SETSIZE)) |
76 "ngx_select_add_event: NGX_ONESHOT_EVENT is not supported"); | 76 { |
77 | 77 ngx_log_error(NGX_LOG_ERR, ev->log, 0, |
78 fds = ngx_select_get_fd_set(cn->fd, event, ev->log); | 78 "maximum number of descriptors " |
79 if (fds == NULL) | 79 "supported by select() is %d", FD_SETSIZE); |
80 return -1; | 80 return NGX_ERROR; |
81 } | |
82 | |
83 if (event == NGX_READ_EVENT) { | |
84 FD_SET(c->fd, &master_read_fd_set); | |
85 max_read++; | |
86 | |
87 } else if (event == NGX_WRITE_EVENT) { | |
88 FD_SET(c->fd, &master_write_fd_set); | |
89 max_write++; | |
90 } | |
91 #else | |
92 if (event == NGX_READ_EVENT) | |
93 FD_SET(c->fd, &master_read_fd_set); | |
94 | |
95 else if (event == NGX_WRITE_EVENT) | |
96 FD_SET(c->fd, &master_write_fd_set); | |
97 | |
98 if (max_fd != -1 && max_fd < c->fd) | |
99 max_fd = c->fd; | |
100 | |
101 #endif | |
102 | |
103 ev->oneshot = (flags & NGX_ONESHOT_EVENT) ? 1: 0; | |
81 | 104 |
82 ev->prev = &event_queue; | 105 ev->prev = &event_queue; |
83 ev->next = event_queue.next; | 106 ev->next = event_queue.next; |
84 event_queue.next->prev = ev; | 107 event_queue.next->prev = ev; |
85 event_queue.next = ev; | 108 event_queue.next = ev; |
86 | 109 |
87 FD_SET(cn->fd, fds); | 110 return NGX_OK; |
88 | |
89 #if (WIN32) | |
90 switch (event) { | |
91 case NGX_READ_EVENT: | |
92 max_read++; | |
93 break; | |
94 case NGX_WRITE_EVENT: | |
95 max_write++; | |
96 break; | |
97 } | |
98 #else | |
99 if (max_fd != -1 && max_fd < cn->fd) | |
100 max_fd = cn->fd; | |
101 #endif | |
102 | |
103 return 0; | |
104 } | 111 } |
105 | 112 |
106 int ngx_select_del_event(ngx_event_t *ev, int event) | 113 int ngx_select_del_event(ngx_event_t *ev, int event) |
107 { | 114 { |
108 fd_set *fds; | 115 ngx_connection_t *c; |
109 ngx_connection_t *cn = (ngx_connection_t *) ev->data; | 116 c = (ngx_connection_t *) ev->data; |
110 | 117 |
111 if (event == NGX_TIMER_EVENT) { | 118 #if (WIN32) |
112 ngx_del_timer(ev); | 119 if (event == NGX_READ_EVENT) { |
113 return 0; | 120 FD_CLR(c->fd, &master_read_fd_set); |
114 } | 121 max_read--; |
115 | 122 |
116 fds = ngx_select_get_fd_set(cn->fd, event, ev->log); | 123 } else if (event == NGX_WRITE_EVENT) { |
117 if (fds == NULL) | 124 FD_CLR(c->fd, &master_write_fd_set); |
118 return -1; | 125 max_write--; |
126 } | |
127 #else | |
128 if (event == NGX_READ_EVENT) | |
129 FD_CLR(c->fd, &master_read_fd_set); | |
130 | |
131 else if (event == NGX_WRITE_EVENT) | |
132 FD_CLR(c->fd, &master_write_fd_set); | |
133 | |
134 if (max_fd == c->fd) | |
135 max_fd = -1; | |
136 #endif | |
119 | 137 |
120 if (ev->prev) | 138 if (ev->prev) |
121 ev->prev->next = ev->next; | 139 ev->prev->next = ev->next; |
122 | 140 |
123 if (ev->next) { | 141 if (ev->next) { |
126 } | 144 } |
127 | 145 |
128 if (ev->prev) | 146 if (ev->prev) |
129 ev->next = NULL; | 147 ev->next = NULL; |
130 | 148 |
131 FD_CLR(cn->fd, fds); | 149 return NGX_OK; |
132 | |
133 #if (WIN32) | |
134 switch (event) { | |
135 case NGX_READ_EVENT: | |
136 max_read--; | |
137 break; | |
138 case NGX_WRITE_EVENT: | |
139 max_write--; | |
140 break; | |
141 } | |
142 #else | |
143 if (max_fd == cn->fd) | |
144 max_fd = -1; | |
145 #endif | |
146 | |
147 return 0; | |
148 } | |
149 | |
150 static fd_set *ngx_select_get_fd_set(ngx_socket_t fd, int event, ngx_log_t *log) | |
151 { | |
152 ngx_log_debug(log, "ngx_select_get_fd_set: %d %d" _ fd _ event); | |
153 | |
154 #if !(WIN32) | |
155 if (fd >= FD_SETSIZE) { | |
156 ngx_log_error(NGX_LOG_ERR, log, 0, | |
157 "ngx_select_get_event: maximum descriptor number" | |
158 "supported by select() is %d", | |
159 FD_SETSIZE - 1); | |
160 return NULL; | |
161 } | |
162 #endif | |
163 | |
164 switch (event) { | |
165 case NGX_READ_EVENT: | |
166 #if (WIN32) | |
167 if (max_read >= FD_SETSIZE) { | |
168 ngx_log_error(NGX_LOG_ERR, log, 0, | |
169 "ngx_select_get_event: maximum number of descriptors " | |
170 "supported by select() is %d", | |
171 FD_SETSIZE); | |
172 return NULL; | |
173 } | |
174 #endif | |
175 return &master_read_fds; | |
176 | |
177 case NGX_WRITE_EVENT: | |
178 #if (WIN32) | |
179 if (max_write >= FD_SETSIZE) { | |
180 ngx_log_error(NGX_LOG_ERR, log, 0, | |
181 "ngx_select_get_event: maximum number of descriptors " | |
182 "supported by select() is %d", | |
183 FD_SETSIZE); | |
184 return NULL; | |
185 } | |
186 #endif | |
187 return &master_write_fds; | |
188 | |
189 default: | |
190 ngx_assert(0, return NULL, log, | |
191 "ngx_select_get_fd_set: invalid event %d" _ event); | |
192 } | |
193 | |
194 return NULL; | |
195 } | 150 } |
196 | 151 |
197 int ngx_select_process_events(ngx_log_t *log) | 152 int ngx_select_process_events(ngx_log_t *log) |
198 { | 153 { |
199 int ready, found; | 154 int ready, found; |
200 u_int timer, delta; | 155 u_int timer, delta; |
201 ngx_event_t *ev, *nx; | 156 ngx_event_t *ev, *nx; |
202 ngx_connection_t *cn; | 157 ngx_connection_t *c; |
203 struct timeval tv, *tp; | 158 struct timeval tv, *tp; |
204 | 159 |
205 work_read_fds = master_read_fds; | 160 work_read_fd_set = master_read_fd_set; |
206 work_write_fds = master_write_fds; | 161 work_write_fd_set = master_write_fd_set; |
207 | 162 |
208 if (timer_queue.timer_next != &timer_queue) { | 163 if (timer_queue.timer_next != &timer_queue) { |
209 timer = timer_queue.timer_next->timer_delta; | 164 timer = timer_queue.timer_next->timer_delta; |
210 tv.tv_sec = timer / 1000; | 165 tv.tv_sec = timer / 1000; |
211 tv.tv_usec = (timer % 1000) * 1000; | 166 tv.tv_usec = (timer % 1000) * 1000; |
220 } | 175 } |
221 | 176 |
222 #if !(WIN32) | 177 #if !(WIN32) |
223 if (max_fd == -1) { | 178 if (max_fd == -1) { |
224 for (ev = event_queue.next; ev != &event_queue; ev = ev->next) { | 179 for (ev = event_queue.next; ev != &event_queue; ev = ev->next) { |
225 cn = (ngx_connection_t *) ev->data; | 180 c = (ngx_connection_t *) ev->data; |
226 if (max_fd < cn->fd) | 181 if (max_fd < c->fd) |
227 max_fd = cn->fd; | 182 max_fd = c->fd; |
228 } | 183 } |
229 | 184 |
230 ngx_log_debug(log, "ngx_select_process_events: change max_fd: %d" _ | 185 ngx_log_debug(log, "change max_fd: %d" _ max_fd); |
231 max_fd); | |
232 } | 186 } |
233 #endif | 187 #endif |
234 | 188 |
235 ngx_log_debug(log, "ngx_select_process_events: timer: %d" _ timer); | 189 ngx_log_debug(log, "ngx_select_process_events: timer: %d" _ timer); |
236 | 190 |
237 #if (WIN32) | 191 #if (WIN32) |
238 if ((ready = select(0, &work_read_fds, &work_write_fds, NULL, tp)) | 192 if ((ready = select(0, &work_read_fd_set, &work_write_fd_set, NULL, tp)) |
239 #else | 193 #else |
240 if ((ready = select(max_fd + 1, &work_read_fds, &work_write_fds, NULL, tp)) | 194 if ((ready = select(max_fd + 1, &work_read_fd_set, &work_write_fd_set, |
195 NULL, tp)) | |
241 #endif | 196 #endif |
242 == -1) { | 197 == -1) { |
243 ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno, | 198 ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno, |
244 "ngx_select_process_events: select failed"); | 199 "ngx_select_process_events: select failed"); |
245 return -1; | 200 return NGX_ERROR; |
246 } | 201 } |
247 | 202 |
248 ngx_log_debug(log, "ngx_select_process_events: ready %d" _ ready); | 203 ngx_log_debug(log, "ngx_select_process_events: ready %d" _ ready); |
249 | 204 |
250 if (timer) { | 205 if (timer) { |
251 delta = ngx_msec() - delta; | 206 delta = ngx_msec() - delta; |
252 | 207 |
253 } else { | 208 } else { |
254 ngx_assert((ready != 0), return -1, log, | 209 ngx_assert((ready != 0), return NGX_ERROR, log, |
255 "ngx_select_process_events: " | 210 "ngx_select_process_events: " |
256 "select returns no events without timeout"); | 211 "select returns no events without timeout"); |
257 } | 212 } |
258 | 213 |
259 ngx_log_debug(log, "ngx_select_process_events: " | 214 ngx_log_debug(log, "ngx_select_process_events: " |
266 /* void */) | 221 /* void */) |
267 { | 222 { |
268 delta -= ev->timer_delta; | 223 delta -= ev->timer_delta; |
269 nx = ev->timer_next; | 224 nx = ev->timer_next; |
270 ngx_del_timer(ev); | 225 ngx_del_timer(ev); |
271 #if 1 | |
272 ev->timedout = 1; | 226 ev->timedout = 1; |
273 if (ev->event_handler(ev) == -1) | 227 if (ev->event_handler(ev) == -1) |
274 ev->close_handler(ev); | 228 ev->close_handler(ev); |
275 #else | |
276 if (ev->timer_handler(ev) == -1) | |
277 ev->close_handler(ev); | |
278 #endif | |
279 ev = nx; | 229 ev = nx; |
280 } | 230 } |
281 | 231 |
282 } else { | 232 } else { |
283 timer_queue.timer_next->timer_delta -= delta; | 233 timer_queue.timer_next->timer_delta -= delta; |
284 } | 234 } |
285 } | 235 } |
286 | 236 |
287 for (ev = event_queue.next; ev != &event_queue; ev = ev->next) { | 237 for (ev = event_queue.next; ev != &event_queue; ev = ev->next) { |
288 cn = (ngx_connection_t *) ev->data; | 238 c = (ngx_connection_t *) ev->data; |
289 found = 0; | 239 found = 0; |
290 | 240 |
291 if (ev->write) { | 241 if (ev->write) { |
292 if (FD_ISSET(cn->fd, &work_write_fds)) { | 242 if (FD_ISSET(c->fd, &work_write_fd_set)) { |
293 ngx_log_debug(log, "ngx_select_process_events: write %d" _ | 243 ngx_log_debug(log, "ngx_select_process_events: write %d" _ |
294 cn->fd); | 244 c->fd); |
295 found = 1; | 245 found = 1; |
296 } | 246 } |
297 | 247 |
298 } else { | 248 } else { |
299 if (FD_ISSET(cn->fd, &work_read_fds)) { | 249 if (FD_ISSET(c->fd, &work_read_fd_set)) { |
300 ngx_log_debug(log, "ngx_select_process_events: read %d" _ | 250 ngx_log_debug(log, "ngx_select_process_events: read %d" _ |
301 cn->fd); | 251 c->fd); |
302 found = 1; | 252 found = 1; |
303 } | 253 } |
304 } | 254 } |
305 | 255 |
306 if (found) { | 256 if (found) { |
307 ev->ready = 1; | 257 ev->ready = 1; |
258 | |
259 if (ev->oneshot) { | |
260 ngx_del_timer(ev); | |
261 if (ev->write) | |
262 ngx_select_del_event(ev, NGX_WRITE_EVENT); | |
263 else | |
264 ngx_select_del_event(ev, NGX_READ_EVENT); | |
265 } | |
266 | |
308 if (ev->event_handler(ev) == -1) | 267 if (ev->event_handler(ev) == -1) |
309 ev->close_handler(ev); | 268 ev->close_handler(ev); |
310 | 269 |
311 ready--; | 270 ready--; |
312 } | 271 } |
313 | 272 |
314 } | 273 } |
315 | 274 |
316 ngx_assert((ready == 0), return 0, log, | 275 ngx_assert((ready == 0), /* void */ ; , log, |
317 "ngx_select_process_events: ready != events"); | 276 "ngx_select_process_events: ready != events"); |
318 | 277 |
319 return 0; | 278 return NGX_OK; |
320 } | 279 } |
321 | 280 |
322 static void ngx_add_timer_core(ngx_event_t *ev, u_int timer) | 281 void ngx_select_add_timer(ngx_event_t *ev, ngx_msec_t timer) |
323 { | 282 { |
324 ngx_event_t *e; | 283 ngx_event_t *e; |
325 | 284 |
326 for (e = timer_queue.timer_next; | 285 for (e = timer_queue.timer_next; |
327 e != &timer_queue && timer > e->timer_delta; | 286 e != &timer_queue && timer > e->timer_delta; |
334 ev->timer_prev = e->timer_prev; | 293 ev->timer_prev = e->timer_prev; |
335 | 294 |
336 e->timer_prev->timer_next = ev; | 295 e->timer_prev->timer_next = ev; |
337 e->timer_prev = ev; | 296 e->timer_prev = ev; |
338 } | 297 } |
339 | |
340 #if 0 | |
341 static void ngx_inline ngx_del_timer(ngx_event_t *ev) | |
342 { | |
343 if (ev->timer_prev) | |
344 ev->timer_prev->timer_next = ev->timer_next; | |
345 | |
346 if (ev->timer_next) { | |
347 ev->timer_next->timer_prev = ev->timer_prev; | |
348 ev->timer_next = NULL; | |
349 } | |
350 | |
351 if (ev->timer_prev) | |
352 ev->timer_prev = NULL; | |
353 } | |
354 #endif |