Mercurial > hg > nginx-vendor-current
comparison src/event/modules/ngx_select_module.c @ 484:ed5e10fb40fc NGINX_0_7_54
nginx 0.7.54
*) Feature: the ngx_http_image_filter_module.
*) Feature: the "proxy_ignore_headers" and "fastcgi_ignore_headers"
directives.
*) Bugfix: a segmentation fault might occur in worker process, if an
"open_file_cache_errors off" directive was used; the bug had
appeared in 0.7.53.
*) Bugfix: the "port_in_redirect off" directive did not work; the bug
had appeared in 0.7.39.
*) Bugfix: improve handling of "select" method errors.
*) Bugfix: of "select() failed (10022: ...)" error in nginx/Windows.
*) Bugfix: in error text descriptions in nginx/Windows; the bug had
appeared in 0.7.53.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Fri, 01 May 2009 00:00:00 +0400 |
parents | 12defd37f578 |
children | 6484cbba0222 |
comparison
equal
deleted
inserted
replaced
483:0a2f4b42ddad | 484:ed5e10fb40fc |
---|---|
16 ngx_uint_t flags); | 16 ngx_uint_t flags); |
17 static ngx_int_t ngx_select_del_event(ngx_event_t *ev, ngx_int_t event, | 17 static ngx_int_t ngx_select_del_event(ngx_event_t *ev, ngx_int_t event, |
18 ngx_uint_t flags); | 18 ngx_uint_t flags); |
19 static ngx_int_t ngx_select_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, | 19 static ngx_int_t ngx_select_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, |
20 ngx_uint_t flags); | 20 ngx_uint_t flags); |
21 static void ngx_select_repair_fd_sets(ngx_cycle_t *cycle); | |
21 static char *ngx_select_init_conf(ngx_cycle_t *cycle, void *conf); | 22 static char *ngx_select_init_conf(ngx_cycle_t *cycle, void *conf); |
22 | 23 |
23 | 24 |
24 static fd_set master_read_fd_set; | 25 static fd_set master_read_fd_set; |
25 static fd_set master_write_fd_set; | 26 static fd_set master_write_fd_set; |
246 | 247 |
247 static ngx_int_t | 248 static ngx_int_t |
248 ngx_select_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, | 249 ngx_select_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, |
249 ngx_uint_t flags) | 250 ngx_uint_t flags) |
250 { | 251 { |
251 int ready, nready; | 252 int ready, nready; |
252 ngx_uint_t i, found; | 253 ngx_err_t err; |
253 ngx_err_t err; | 254 ngx_uint_t i, found; |
254 ngx_event_t *ev, **queue; | 255 ngx_event_t *ev, **queue; |
255 ngx_connection_t *c; | 256 struct timeval tv, *tp; |
256 struct timeval tv, *tp; | 257 ngx_connection_t *c; |
257 | 258 |
258 #if !(NGX_WIN32) | 259 #if !(NGX_WIN32) |
259 | 260 |
260 if (max_fd == -1) { | 261 if (max_fd == -1) { |
261 for (i = 0; i < nevents; i++) { | 262 for (i = 0; i < nevents; i++) { |
300 "select timer: %M", timer); | 301 "select timer: %M", timer); |
301 | 302 |
302 work_read_fd_set = master_read_fd_set; | 303 work_read_fd_set = master_read_fd_set; |
303 work_write_fd_set = master_write_fd_set; | 304 work_write_fd_set = master_write_fd_set; |
304 | 305 |
305 #if 1 | 306 #if (NGX_WIN32) |
306 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, | 307 |
307 /* | 308 if (max_read || max_write) { |
308 * (void *) disables "dereferencing type-punned | 309 ready = select(0, &work_read_fd_set, &work_write_fd_set, NULL, tp); |
309 * pointer will break strict-aliasing rules | 310 |
310 */ | 311 } else { |
311 "select read fd_set: %08Xd", | 312 |
312 *(int *) (void *) &work_read_fd_set); | 313 /* |
313 #endif | 314 * Winsock select() requires that at least one descriptor set must be |
314 | 315 * be non-null, and any non-null descriptor set must contain at least |
315 #if (NGX_WIN32) | 316 * one handle to a socket. Otherwise select() returns WSAEINVAL. |
316 | 317 */ |
317 ready = select(0, &work_read_fd_set, &work_write_fd_set, NULL, tp); | 318 |
319 ngx_msleep(timer); | |
320 | |
321 ready = 0; | |
322 } | |
318 | 323 |
319 #else | 324 #else |
320 | 325 |
321 ready = select(max_fd + 1, &work_read_fd_set, &work_write_fd_set, NULL, tp); | 326 ready = select(max_fd + 1, &work_read_fd_set, &work_write_fd_set, NULL, tp); |
322 | 327 |
337 | 342 |
338 #if (NGX_WIN32) | 343 #if (NGX_WIN32) |
339 | 344 |
340 if (err) { | 345 if (err) { |
341 ngx_log_error(NGX_LOG_ALERT, cycle->log, err, "select() failed"); | 346 ngx_log_error(NGX_LOG_ALERT, cycle->log, err, "select() failed"); |
347 | |
348 if (err == WSAENOTSOCK) { | |
349 ngx_select_repair_fd_sets(cycle); | |
350 } | |
351 | |
342 return NGX_ERROR; | 352 return NGX_ERROR; |
343 } | 353 } |
344 | 354 |
345 #else | 355 #else |
346 | 356 |
359 } else { | 369 } else { |
360 level = NGX_LOG_ALERT; | 370 level = NGX_LOG_ALERT; |
361 } | 371 } |
362 | 372 |
363 ngx_log_error(level, cycle->log, err, "select() failed"); | 373 ngx_log_error(level, cycle->log, err, "select() failed"); |
374 | |
375 if (err == EBADF) { | |
376 ngx_select_repair_fd_sets(cycle); | |
377 } | |
378 | |
364 return NGX_ERROR; | 379 return NGX_ERROR; |
365 } | 380 } |
366 | 381 |
367 #endif | 382 #endif |
368 | 383 |
412 } | 427 } |
413 | 428 |
414 ngx_mutex_unlock(ngx_posted_events_mutex); | 429 ngx_mutex_unlock(ngx_posted_events_mutex); |
415 | 430 |
416 if (ready != nready) { | 431 if (ready != nready) { |
417 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "select ready != events"); | 432 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, |
433 "select ready != events: %d:%d", ready, nready); | |
434 | |
435 ngx_select_repair_fd_sets(cycle); | |
418 } | 436 } |
419 | 437 |
420 return NGX_OK; | 438 return NGX_OK; |
439 } | |
440 | |
441 | |
442 static void | |
443 ngx_select_repair_fd_sets(ngx_cycle_t *cycle) | |
444 { | |
445 int n; | |
446 socklen_t len; | |
447 ngx_err_t err; | |
448 ngx_socket_t s; | |
449 | |
450 #if (NGX_WIN32) | |
451 u_int i; | |
452 | |
453 for (i = 0; i < master_read_fd_set.fd_count; i++) { | |
454 | |
455 s = master_read_fd_set.fd_array[i]; | |
456 len = sizeof(int); | |
457 | |
458 if (getsockopt(s, SOL_SOCKET, SO_TYPE, (char *) &n, &len) == -1) { | |
459 err = ngx_socket_errno; | |
460 | |
461 ngx_log_error(NGX_LOG_ALERT, cycle->log, err, | |
462 "invalid descriptor #%d in read fd_set", s); | |
463 | |
464 FD_CLR(s, &master_read_fd_set); | |
465 } | |
466 } | |
467 | |
468 for (i = 0; i < master_write_fd_set.fd_count; i++) { | |
469 | |
470 s = master_write_fd_set.fd_array[i]; | |
471 len = sizeof(int); | |
472 | |
473 if (getsockopt(s, SOL_SOCKET, SO_TYPE, (char *) &n, &len) == -1) { | |
474 err = ngx_socket_errno; | |
475 | |
476 ngx_log_error(NGX_LOG_ALERT, cycle->log, err, | |
477 "invalid descriptor #%d in write fd_set", s); | |
478 | |
479 FD_CLR(s, &master_write_fd_set); | |
480 } | |
481 } | |
482 | |
483 #else | |
484 | |
485 for (s = 0; s <= max_fd; s++) { | |
486 | |
487 if (FD_ISSET(s, &master_read_fd_set) == 0) { | |
488 continue; | |
489 } | |
490 | |
491 len = sizeof(int); | |
492 | |
493 if (getsockopt(s, SOL_SOCKET, SO_TYPE, &n, &len) == -1) { | |
494 err = ngx_socket_errno; | |
495 | |
496 ngx_log_error(NGX_LOG_ALERT, cycle->log, err, | |
497 "invalid descriptor #%d in read fd_set", s); | |
498 | |
499 FD_CLR(s, &master_read_fd_set); | |
500 } | |
501 } | |
502 | |
503 for (s = 0; s <= max_fd; s++) { | |
504 | |
505 if (FD_ISSET(s, &master_write_fd_set) == 0) { | |
506 continue; | |
507 } | |
508 | |
509 len = sizeof(int); | |
510 | |
511 if (getsockopt(s, SOL_SOCKET, SO_TYPE, &n, &len) == -1) { | |
512 err = ngx_socket_errno; | |
513 | |
514 ngx_log_error(NGX_LOG_ALERT, cycle->log, err, | |
515 "invalid descriptor #%d in write fd_set", s); | |
516 | |
517 FD_CLR(s, &master_write_fd_set); | |
518 } | |
519 } | |
520 | |
521 max_fd = -1; | |
522 | |
523 #endif | |
421 } | 524 } |
422 | 525 |
423 | 526 |
424 static char * | 527 static char * |
425 ngx_select_init_conf(ngx_cycle_t *cycle, void *conf) | 528 ngx_select_init_conf(ngx_cycle_t *cycle, void *conf) |