comparison src/event/modules/ngx_select_module.c @ 488:829f9a66a659 NGINX_0_7_56

nginx 0.7.56 *) Feature: nginx/Windows supports IPv6 in a "listen" directive of the HTTP module. *) Bugfix: in ngx_http_image_filter_module.
author Igor Sysoev <http://sysoev.ru>
date Mon, 11 May 2009 00:00:00 +0400
parents 6484cbba0222
children 86dad910eeb6
comparison
equal deleted inserted replaced
487:e98b980b4fe7 488:829f9a66a659
5 5
6 6
7 #include <ngx_config.h> 7 #include <ngx_config.h>
8 #include <ngx_core.h> 8 #include <ngx_core.h>
9 #include <ngx_event.h> 9 #include <ngx_event.h>
10
11 10
12 11
13 static ngx_int_t ngx_select_init(ngx_cycle_t *cycle, ngx_msec_t timer); 12 static ngx_int_t ngx_select_init(ngx_cycle_t *cycle, ngx_msec_t timer);
14 static void ngx_select_done(ngx_cycle_t *cycle); 13 static void ngx_select_done(ngx_cycle_t *cycle);
15 static ngx_int_t ngx_select_add_event(ngx_event_t *ev, ngx_int_t event, 14 static ngx_int_t ngx_select_add_event(ngx_event_t *ev, ngx_int_t event,
25 static fd_set master_read_fd_set; 24 static fd_set master_read_fd_set;
26 static fd_set master_write_fd_set; 25 static fd_set master_write_fd_set;
27 static fd_set work_read_fd_set; 26 static fd_set work_read_fd_set;
28 static fd_set work_write_fd_set; 27 static fd_set work_write_fd_set;
29 28
30 #if (NGX_WIN32)
31 static ngx_uint_t max_read;
32 static ngx_uint_t max_write;
33 #else
34 static ngx_int_t max_fd; 29 static ngx_int_t max_fd;
35 #endif
36
37 static ngx_uint_t nevents; 30 static ngx_uint_t nevents;
38 31
39 static ngx_event_t **event_index; 32 static ngx_event_t **event_index;
40 33
41 34
110 103
111 ngx_event_actions = ngx_select_module_ctx.actions; 104 ngx_event_actions = ngx_select_module_ctx.actions;
112 105
113 ngx_event_flags = NGX_USE_LEVEL_EVENT; 106 ngx_event_flags = NGX_USE_LEVEL_EVENT;
114 107
115 #if (NGX_WIN32)
116 max_read = max_write = 0;
117 #else
118 max_fd = -1; 108 max_fd = -1;
119 #endif
120 109
121 return NGX_OK; 110 return NGX_OK;
122 } 111 }
123 112
124 113
154 "invalid select %s event fd:%d ev:%i", 143 "invalid select %s event fd:%d ev:%i",
155 ev->write ? "write" : "read", c->fd, event); 144 ev->write ? "write" : "read", c->fd, event);
156 return NGX_ERROR; 145 return NGX_ERROR;
157 } 146 }
158 147
159
160 #if (NGX_WIN32)
161
162 if ((event == NGX_READ_EVENT) && (max_read >= FD_SETSIZE)
163 || (event == NGX_WRITE_EVENT) && (max_write >= FD_SETSIZE))
164 {
165 ngx_log_error(NGX_LOG_ERR, ev->log, 0,
166 "maximum number of descriptors "
167 "supported by select() is %d", FD_SETSIZE);
168 return NGX_ERROR;
169 }
170
171 if (event == NGX_READ_EVENT) { 148 if (event == NGX_READ_EVENT) {
172 FD_SET(c->fd, &master_read_fd_set); 149 FD_SET(c->fd, &master_read_fd_set);
173 max_read++;
174 150
175 } else if (event == NGX_WRITE_EVENT) { 151 } else if (event == NGX_WRITE_EVENT) {
176 FD_SET(c->fd, &master_write_fd_set); 152 FD_SET(c->fd, &master_write_fd_set);
177 max_write++;
178 }
179
180 #else
181
182 if (event == NGX_READ_EVENT) {
183 FD_SET(c->fd, &master_read_fd_set);
184
185 } else if (event == NGX_WRITE_EVENT) {
186 FD_SET(c->fd, &master_write_fd_set);
187 } 153 }
188 154
189 if (max_fd != -1 && max_fd < c->fd) { 155 if (max_fd != -1 && max_fd < c->fd) {
190 max_fd = c->fd; 156 max_fd = c->fd;
191 } 157 }
192
193 #endif
194 158
195 ev->active = 1; 159 ev->active = 1;
196 160
197 event_index[nevents] = ev; 161 event_index[nevents] = ev;
198 ev->index = nevents; 162 ev->index = nevents;
217 } 181 }
218 182
219 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0, 183 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
220 "select del event fd:%d ev:%i", c->fd, event); 184 "select del event fd:%d ev:%i", c->fd, event);
221 185
222 #if (NGX_WIN32)
223
224 if (event == NGX_READ_EVENT) { 186 if (event == NGX_READ_EVENT) {
225 FD_CLR(c->fd, &master_read_fd_set); 187 FD_CLR(c->fd, &master_read_fd_set);
226 max_read--;
227 188
228 } else if (event == NGX_WRITE_EVENT) { 189 } else if (event == NGX_WRITE_EVENT) {
229 FD_CLR(c->fd, &master_write_fd_set); 190 FD_CLR(c->fd, &master_write_fd_set);
230 max_write--;
231 }
232
233 #else
234
235 if (event == NGX_READ_EVENT) {
236 FD_CLR(c->fd, &master_read_fd_set);
237
238 } else if (event == NGX_WRITE_EVENT) {
239 FD_CLR(c->fd, &master_write_fd_set);
240 } 191 }
241 192
242 if (max_fd == c->fd) { 193 if (max_fd == c->fd) {
243 max_fd = -1; 194 max_fd = -1;
244 } 195 }
245
246 #endif
247 196
248 if (ev->index < --nevents) { 197 if (ev->index < --nevents) {
249 e = event_index[nevents]; 198 e = event_index[nevents];
250 event_index[ev->index] = e; 199 event_index[ev->index] = e;
251 e->index = ev->index; 200 e->index = ev->index;
266 ngx_uint_t i, found; 215 ngx_uint_t i, found;
267 ngx_event_t *ev, **queue; 216 ngx_event_t *ev, **queue;
268 struct timeval tv, *tp; 217 struct timeval tv, *tp;
269 ngx_connection_t *c; 218 ngx_connection_t *c;
270 219
271 #if !(NGX_WIN32)
272
273 if (max_fd == -1) { 220 if (max_fd == -1) {
274 for (i = 0; i < nevents; i++) { 221 for (i = 0; i < nevents; i++) {
275 c = event_index[i]->data; 222 c = event_index[i]->data;
276 if (max_fd < c->fd) { 223 if (max_fd < c->fd) {
277 max_fd = c->fd; 224 max_fd = c->fd;
279 } 226 }
280 227
281 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, 228 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
282 "change max_fd: %d", max_fd); 229 "change max_fd: %d", max_fd);
283 } 230 }
284
285 #endif
286 231
287 #if (NGX_DEBUG) 232 #if (NGX_DEBUG)
288 if (cycle->log->log_level & NGX_LOG_DEBUG_ALL) { 233 if (cycle->log->log_level & NGX_LOG_DEBUG_ALL) {
289 for (i = 0; i < nevents; i++) { 234 for (i = 0; i < nevents; i++) {
290 ev = event_index[i]; 235 ev = event_index[i];
291 c = ev->data; 236 c = ev->data;
292 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, 237 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
293 "select event: fd:%d wr:%d", c->fd, ev->write); 238 "select event: fd:%d wr:%d", c->fd, ev->write);
294 } 239 }
295 240
296 #if !(NGX_WIN32)
297 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, 241 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
298 "max_fd: %d", max_fd); 242 "max_fd: %d", max_fd);
299 #endif
300 } 243 }
301 #endif 244 #endif
302 245
303 if (timer == NGX_TIMER_INFINITE) { 246 if (timer == NGX_TIMER_INFINITE) {
304 tp = NULL; 247 tp = NULL;
313 "select timer: %M", timer); 256 "select timer: %M", timer);
314 257
315 work_read_fd_set = master_read_fd_set; 258 work_read_fd_set = master_read_fd_set;
316 work_write_fd_set = master_write_fd_set; 259 work_write_fd_set = master_write_fd_set;
317 260
318 #if (NGX_WIN32)
319
320 if (max_read || max_write) {
321 ready = select(0, &work_read_fd_set, &work_write_fd_set, NULL, tp);
322
323 } else {
324
325 /*
326 * Winsock select() requires that at least one descriptor set must be
327 * be non-null, and any non-null descriptor set must contain at least
328 * one handle to a socket. Otherwise select() returns WSAEINVAL.
329 */
330
331 ngx_msleep(timer);
332
333 ready = 0;
334 }
335
336 #else
337
338 ready = select(max_fd + 1, &work_read_fd_set, &work_write_fd_set, NULL, tp); 261 ready = select(max_fd + 1, &work_read_fd_set, &work_write_fd_set, NULL, tp);
339
340 #endif
341 262
342 if (ready == -1) { 263 if (ready == -1) {
343 err = ngx_socket_errno; 264 err = ngx_socket_errno;
344 } else { 265 } else {
345 err = 0; 266 err = 0;
350 } 271 }
351 272
352 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, 273 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
353 "select ready %d", ready); 274 "select ready %d", ready);
354 275
355 #if (NGX_WIN32)
356
357 if (err) {
358 ngx_log_error(NGX_LOG_ALERT, cycle->log, err, "select() failed");
359
360 if (err == WSAENOTSOCK) {
361 ngx_select_repair_fd_sets(cycle);
362 }
363
364 return NGX_ERROR;
365 }
366
367 #else
368
369 if (err) { 276 if (err) {
370 ngx_uint_t level; 277 ngx_uint_t level;
371 278
372 if (err == NGX_EINTR) { 279 if (err == NGX_EINTR) {
373 280
388 ngx_select_repair_fd_sets(cycle); 295 ngx_select_repair_fd_sets(cycle);
389 } 296 }
390 297
391 return NGX_ERROR; 298 return NGX_ERROR;
392 } 299 }
393
394 #endif
395 300
396 if (ready == 0) { 301 if (ready == 0) {
397 if (timer != NGX_TIMER_INFINITE) { 302 if (timer != NGX_TIMER_INFINITE) {
398 return NGX_OK; 303 return NGX_OK;
399 } 304 }
457 int n; 362 int n;
458 socklen_t len; 363 socklen_t len;
459 ngx_err_t err; 364 ngx_err_t err;
460 ngx_socket_t s; 365 ngx_socket_t s;
461 366
462 #if (NGX_WIN32) 367 for (s = 0; s <= max_fd; s++) {
463 u_int i; 368
464 369 if (FD_ISSET(s, &master_read_fd_set) == 0) {
465 for (i = 0; i < master_read_fd_set.fd_count; i++) { 370 continue;
466 371 }
467 s = master_read_fd_set.fd_array[i]; 372
468 len = sizeof(int); 373 len = sizeof(int);
469 374
470 if (getsockopt(s, SOL_SOCKET, SO_TYPE, (char *) &n, &len) == -1) { 375 if (getsockopt(s, SOL_SOCKET, SO_TYPE, &n, &len) == -1) {
471 err = ngx_socket_errno; 376 err = ngx_socket_errno;
472 377
473 ngx_log_error(NGX_LOG_ALERT, cycle->log, err, 378 ngx_log_error(NGX_LOG_ALERT, cycle->log, err,
474 "invalid descriptor #%d in read fd_set", s); 379 "invalid descriptor #%d in read fd_set", s);
475 380
476 FD_CLR(s, &master_read_fd_set); 381 FD_CLR(s, &master_read_fd_set);
477 } 382 }
478 } 383 }
479 384
480 for (i = 0; i < master_write_fd_set.fd_count; i++) { 385 for (s = 0; s <= max_fd; s++) {
481 386
482 s = master_write_fd_set.fd_array[i]; 387 if (FD_ISSET(s, &master_write_fd_set) == 0) {
388 continue;
389 }
390
483 len = sizeof(int); 391 len = sizeof(int);
484 392
485 if (getsockopt(s, SOL_SOCKET, SO_TYPE, (char *) &n, &len) == -1) { 393 if (getsockopt(s, SOL_SOCKET, SO_TYPE, &n, &len) == -1) {
486 err = ngx_socket_errno; 394 err = ngx_socket_errno;
487 395
488 ngx_log_error(NGX_LOG_ALERT, cycle->log, err, 396 ngx_log_error(NGX_LOG_ALERT, cycle->log, err,
489 "invalid descriptor #%d in write fd_set", s); 397 "invalid descriptor #%d in write fd_set", s);
490 398
491 FD_CLR(s, &master_write_fd_set); 399 FD_CLR(s, &master_write_fd_set);
492 } 400 }
493 } 401 }
494 402
495 #else
496
497 for (s = 0; s <= max_fd; s++) {
498
499 if (FD_ISSET(s, &master_read_fd_set) == 0) {
500 continue;
501 }
502
503 len = sizeof(int);
504
505 if (getsockopt(s, SOL_SOCKET, SO_TYPE, &n, &len) == -1) {
506 err = ngx_socket_errno;
507
508 ngx_log_error(NGX_LOG_ALERT, cycle->log, err,
509 "invalid descriptor #%d in read fd_set", s);
510
511 FD_CLR(s, &master_read_fd_set);
512 }
513 }
514
515 for (s = 0; s <= max_fd; s++) {
516
517 if (FD_ISSET(s, &master_write_fd_set) == 0) {
518 continue;
519 }
520
521 len = sizeof(int);
522
523 if (getsockopt(s, SOL_SOCKET, SO_TYPE, &n, &len) == -1) {
524 err = ngx_socket_errno;
525
526 ngx_log_error(NGX_LOG_ALERT, cycle->log, err,
527 "invalid descriptor #%d in write fd_set", s);
528
529 FD_CLR(s, &master_write_fd_set);
530 }
531 }
532
533 max_fd = -1; 403 max_fd = -1;
534
535 #endif
536 } 404 }
537 405
538 406
539 static char * 407 static char *
540 ngx_select_init_conf(ngx_cycle_t *cycle, void *conf) 408 ngx_select_init_conf(ngx_cycle_t *cycle, void *conf)
546 if (ecf->use != ngx_select_module.ctx_index) { 414 if (ecf->use != ngx_select_module.ctx_index) {
547 return NGX_CONF_OK; 415 return NGX_CONF_OK;
548 } 416 }
549 417
550 /* disable warning: the default FD_SETSIZE is 1024U in FreeBSD 5.x */ 418 /* disable warning: the default FD_SETSIZE is 1024U in FreeBSD 5.x */
551
552 #if !(NGX_WIN32)
553 419
554 if (cycle->connection_n > FD_SETSIZE) { 420 if (cycle->connection_n > FD_SETSIZE) {
555 ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, 421 ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
556 "the maximum number of files " 422 "the maximum number of files "
557 "supported by select() is %ud", FD_SETSIZE); 423 "supported by select() is %ud", FD_SETSIZE);
558 return NGX_CONF_ERROR; 424 return NGX_CONF_ERROR;
559 } 425 }
560 426
561 #endif 427 #if (NGX_THREADS)
562
563 #if (NGX_THREADS) && !(NGX_WIN32)
564 428
565 ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, 429 ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
566 "select() is not supported in the threaded mode"); 430 "select() is not supported in the threaded mode");
567 return NGX_CONF_ERROR; 431 return NGX_CONF_ERROR;
568 432