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)