comparison src/event/modules/ngx_rtsig_module.c @ 112:408f195b3482 NGINX_0_3_3

nginx 0.3.3 *) Change: the "bl" and "af" parameters of the "listen" directive was renamed to the "backlog" and "accept_filter". *) Feature: the "rcvbuf" and "sndbuf" parameters of the "listen" directive. *) Change: the "$msec" log parameter does not require now the additional the gettimeofday() system call. *) Feature: the -t switch now tests the "listen" directives. *) Bugfix: if the invalid address was specified in the "listen" directive, then after the -HUP signal nginx left an open socket in the CLOSED state. *) Bugfix: the mime type may be incorrectly set to default value for index file with variable in the name; bug appeared in 0.3.0. *) Feature: the "timer_resolution" directive. *) Feature: the millisecond "$upstream_response_time" log parameter. *) Bugfix: a temporary file with client request body now is removed just after the response header was transferred to a client. *) Bugfix: OpenSSL 0.9.6 compatibility. *) Bugfix: the SSL certificate and key file paths could not be relative. *) Bugfix: the "ssl_prefer_server_ciphers" directive did not work in the ngx_imap_ssl_module. *) Bugfix: the "ssl_protocols" directive allowed to specify the single protocol only.
author Igor Sysoev <http://sysoev.ru>
date Wed, 19 Oct 2005 00:00:00 +0400
parents cf3d6edb3ad6
children e38f51cd0905
comparison
equal deleted inserted replaced
111:a175b609c76d 112:408f195b3482
36 } ngx_rtsig_conf_t; 36 } ngx_rtsig_conf_t;
37 37
38 38
39 extern ngx_event_module_t ngx_poll_module_ctx; 39 extern ngx_event_module_t ngx_poll_module_ctx;
40 40
41 static ngx_int_t ngx_rtsig_init(ngx_cycle_t *cycle); 41 static ngx_int_t ngx_rtsig_init(ngx_cycle_t *cycle, ngx_msec_t timer);
42 static void ngx_rtsig_done(ngx_cycle_t *cycle); 42 static void ngx_rtsig_done(ngx_cycle_t *cycle);
43 static ngx_int_t ngx_rtsig_add_connection(ngx_connection_t *c); 43 static ngx_int_t ngx_rtsig_add_connection(ngx_connection_t *c);
44 static ngx_int_t ngx_rtsig_del_connection(ngx_connection_t *c, u_int flags); 44 static ngx_int_t ngx_rtsig_del_connection(ngx_connection_t *c, u_int flags);
45 static ngx_int_t ngx_rtsig_process_events(ngx_cycle_t *cycle); 45 static ngx_int_t ngx_rtsig_process_events(ngx_cycle_t *cycle,
46 static ngx_int_t ngx_rtsig_process_overflow(ngx_cycle_t *cycle); 46 ngx_msec_t timer, ngx_uint_t flags);
47 static ngx_int_t ngx_rtsig_process_overflow(ngx_cycle_t *cycle,
48 ngx_msec_t timer, ngx_uint_t flags);
47 49
48 static void *ngx_rtsig_create_conf(ngx_cycle_t *cycle); 50 static void *ngx_rtsig_create_conf(ngx_cycle_t *cycle);
49 static char *ngx_rtsig_init_conf(ngx_cycle_t *cycle, void *conf); 51 static char *ngx_rtsig_init_conf(ngx_cycle_t *cycle, void *conf);
50 static char *ngx_check_ngx_overflow_threshold_bounds(ngx_conf_t *cf, 52 static char *ngx_check_ngx_overflow_threshold_bounds(ngx_conf_t *cf,
51 void *post, void *data); 53 void *post, void *data);
132 NGX_MODULE_V1_PADDING 134 NGX_MODULE_V1_PADDING
133 }; 135 };
134 136
135 137
136 static ngx_int_t 138 static ngx_int_t
137 ngx_rtsig_init(ngx_cycle_t *cycle) 139 ngx_rtsig_init(ngx_cycle_t *cycle, ngx_msec_t timer)
138 { 140 {
139 ngx_rtsig_conf_t *rtscf; 141 ngx_rtsig_conf_t *rtscf;
140 142
141 rtscf = ngx_event_get_conf(cycle->conf_ctx, ngx_rtsig_module); 143 rtscf = ngx_event_get_conf(cycle->conf_ctx, ngx_rtsig_module);
142 144
143 sigemptyset(&set); 145 sigemptyset(&set);
144 sigaddset(&set, rtscf->signo); 146 sigaddset(&set, rtscf->signo);
145 sigaddset(&set, rtscf->signo + 1); 147 sigaddset(&set, rtscf->signo + 1);
146 sigaddset(&set, SIGIO); 148 sigaddset(&set, SIGIO);
149 sigaddset(&set, SIGALRM);
147 150
148 if (sigprocmask(SIG_BLOCK, &set, NULL) == -1) { 151 if (sigprocmask(SIG_BLOCK, &set, NULL) == -1) {
149 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, 152 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
150 "sigprocmask() failed"); 153 "sigprocmask() failed");
151 return NGX_ERROR; 154 return NGX_ERROR;
277 return NGX_OK; 280 return NGX_OK;
278 } 281 }
279 282
280 283
281 static ngx_int_t 284 static ngx_int_t
282 ngx_rtsig_process_events(ngx_cycle_t *cycle) 285 ngx_rtsig_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
283 { 286 {
284 int signo; 287 int signo;
285 ngx_int_t instance; 288 ngx_int_t instance;
286 ngx_msec_t timer, delta; 289 ngx_msec_t delta;
287 ngx_err_t err; 290 ngx_err_t err;
288 siginfo_t si; 291 siginfo_t si;
289 ngx_event_t *rev, *wev; 292 ngx_event_t *rev, *wev;
290 struct timeval tv;
291 struct timespec ts, *tp; 293 struct timespec ts, *tp;
292 struct sigaction sa; 294 struct sigaction sa;
293 ngx_connection_t *c; 295 ngx_connection_t *c;
294 ngx_rtsig_conf_t *rtscf; 296 ngx_rtsig_conf_t *rtscf;
295 297
296 if (overflow) {
297 timer = 0;
298
299 } else {
300 timer = ngx_event_find_timer();
301
302 #if (NGX_THREADS)
303
304 if (timer == NGX_TIMER_ERROR) {
305 return NGX_ERROR;
306 }
307
308 if (timer == NGX_TIMER_INFINITE || timer > 500) {
309 timer = 500;
310 }
311
312 #endif
313
314 if (ngx_accept_mutex) {
315 if (ngx_accept_disabled > 0) {
316 ngx_accept_disabled--;
317
318 } else {
319 ngx_accept_mutex_held = 0;
320
321 if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) {
322 return NGX_ERROR;
323 }
324
325 if (ngx_accept_mutex_held == 0
326 && (timer == NGX_TIMER_INFINITE
327 || timer > ngx_accept_mutex_delay))
328 {
329 timer = ngx_accept_mutex_delay;
330 }
331 }
332 }
333 }
334
335 if (timer == NGX_TIMER_INFINITE) { 298 if (timer == NGX_TIMER_INFINITE) {
336 tp = NULL; 299 tp = NULL;
337 300
338 } else { 301 } else {
339 ts.tv_sec = timer / 1000; 302 ts.tv_sec = timer / 1000;
355 "rtsig signo:%d", signo); 318 "rtsig signo:%d", signo);
356 319
357 if (err == NGX_EAGAIN) { 320 if (err == NGX_EAGAIN) {
358 321
359 if (timer == NGX_TIMER_INFINITE) { 322 if (timer == NGX_TIMER_INFINITE) {
360 ngx_accept_mutex_unlock();
361 ngx_log_error(NGX_LOG_ALERT, cycle->log, err, 323 ngx_log_error(NGX_LOG_ALERT, cycle->log, err,
362 "sigtimedwait() returned EAGAIN without timeout"); 324 "sigtimedwait() returned EAGAIN without timeout");
363 return NGX_ERROR; 325 return NGX_ERROR;
364 } 326 }
365 327
371 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0, 333 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
372 "rtsig signo:%d fd:%d band:%04Xd", 334 "rtsig signo:%d fd:%d band:%04Xd",
373 signo, si.si_fd, si.si_band); 335 signo, si.si_fd, si.si_band);
374 } 336 }
375 337
376 ngx_gettimeofday(&tv); 338 delta = ngx_current_msec;
377 ngx_time_update(tv.tv_sec); 339
378 340 if (flags & NGX_UPDATE_TIME) {
379 delta = ngx_current_time; 341 ngx_time_update(0, 0);
380 ngx_current_time = (ngx_msec_t) tv.tv_sec * 1000 + tv.tv_usec / 1000; 342 }
381 343
382 if (err) { 344 if (err) {
383 ngx_accept_mutex_unlock();
384 ngx_log_error((err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT, 345 ngx_log_error((err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT,
385 cycle->log, err, "sigtimedwait() failed"); 346 cycle->log, err, "sigtimedwait() failed");
386 return NGX_ERROR; 347 return NGX_ERROR;
387 } 348 }
388 349
389 if (timer != NGX_TIMER_INFINITE) { 350 if (timer != NGX_TIMER_INFINITE) {
390 delta = ngx_current_time - delta; 351 delta = ngx_current_msec - delta;
391 352
392 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, 353 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
393 "rtsig timer: %M, delta: %M", timer, delta); 354 "rtsig timer: %M, delta: %M", timer, delta);
394 } 355 }
395 356
402 } 363 }
403 364
404 c = ngx_cycle->files[si.si_fd]; 365 c = ngx_cycle->files[si.si_fd];
405 366
406 if (c == NULL) { 367 if (c == NULL) {
368
407 /* the stale event */ 369 /* the stale event */
408 370
409 ngx_accept_mutex_unlock();
410
411 return NGX_OK; 371 return NGX_OK;
412 } 372 }
413 373
414 instance = signo - rtscf->signo; 374 instance = signo - rtscf->signo;
415 375
416 rev = c->read; 376 rev = c->read;
417 377
418 if (c->read->instance != instance) { 378 if (rev->instance != instance) {
419 379
420 /* 380 /*
421 * the stale event from a file descriptor 381 * the stale event from a file descriptor
422 * that was just closed in this iteration 382 * that was just closed in this iteration
423 */ 383 */
424 384
425 ngx_accept_mutex_unlock();
426
427 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, 385 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
428 "rtsig: stale event %p", c); 386 "rtsig: stale event %p", c);
429 387
430 return NGX_OK; 388 return NGX_OK;
431 } 389 }
432 390
433 if (si.si_band & (POLLIN|POLLHUP|POLLERR)) { 391 if ((si.si_band & (POLLIN|POLLHUP|POLLERR)) && rev->active) {
434 if (rev->active) { 392 rev->ready = 1;
435 393 rev->handler(rev);
436 if (ngx_threaded && !rev->accept) {
437 if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) {
438 ngx_accept_mutex_unlock();
439 return NGX_ERROR;
440 }
441
442 rev->posted_ready = 1;
443 ngx_post_event(rev);
444
445 ngx_mutex_unlock(ngx_posted_events_mutex);
446
447 } else {
448 rev->ready = 1;
449
450 if (!ngx_threaded && !ngx_accept_mutex_held) {
451 rev->handler(rev);
452
453 } else if (rev->accept) {
454 if (ngx_accept_disabled <= 0) {
455 rev->handler(rev);
456 }
457
458 } else {
459 ngx_post_event(rev);
460 }
461 }
462 }
463 } 394 }
464 395
465 wev = c->write; 396 wev = c->write;
466 397
467 if (si.si_band & (POLLOUT|POLLHUP|POLLERR)) { 398 if ((si.si_band & (POLLOUT|POLLHUP|POLLERR)) && wev->active) {
468 if (wev->active) { 399 wev->ready = 1;
469 400 wev->handler(wev);
470 if (ngx_threaded) { 401 }
471 if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) { 402
472 ngx_accept_mutex_unlock(); 403 } else if (signo == SIGALRM) {
473 return NGX_ERROR; 404
474 } 405 return NGX_OK;
475
476 wev->posted_ready = 1;
477 ngx_post_event(wev);
478
479 ngx_mutex_unlock(ngx_posted_events_mutex);
480
481 } else {
482 wev->ready = 1;
483
484 if (!ngx_threaded && !ngx_accept_mutex_held) {
485 wev->handler(wev);
486
487 } else {
488 ngx_post_event(wev);
489 }
490 }
491 }
492 }
493 406
494 } else if (signo == SIGIO) { 407 } else if (signo == SIGIO) {
495 ngx_accept_mutex_unlock();
496 408
497 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, 409 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
498 "rt signal queue overflowed"); 410 "rt signal queue overflowed");
499 411
500 /* flush the RT signal queue */ 412 /* flush the RT signal queue */
518 ngx_event_actions.process_events = ngx_rtsig_process_overflow; 430 ngx_event_actions.process_events = ngx_rtsig_process_overflow;
519 431
520 return NGX_ERROR; 432 return NGX_ERROR;
521 433
522 } else if (signo != -1) { 434 } else if (signo != -1) {
523 ngx_accept_mutex_unlock();
524
525 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, 435 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
526 "sigtimedwait() returned unexpected signal: %d", signo); 436 "sigtimedwait() returned unexpected signal: %d", signo);
527 437
528 return NGX_ERROR; 438 return NGX_ERROR;
529 } 439 }
530 440
531 ngx_accept_mutex_unlock(); 441 if (signo != -1) {
532
533 ngx_event_expire_timers();
534
535 if (ngx_posted_events) {
536 if (ngx_threaded) {
537 ngx_wakeup_worker_thread(cycle);
538
539 } else {
540 ngx_event_process_posted(cycle);
541 }
542 }
543
544 if (signo == -1) {
545 return NGX_AGAIN;
546 } else {
547 return NGX_OK; 442 return NGX_OK;
548 } 443 }
549 } 444
550 445 return NGX_AGAIN;
551 446 }
552 /* TODO: old cylces */ 447
553 448
554 static ngx_int_t 449 static ngx_int_t
555 ngx_rtsig_process_overflow(ngx_cycle_t *cycle) 450 ngx_rtsig_process_overflow(ngx_cycle_t *cycle, ngx_msec_t timer,
451 ngx_uint_t flags)
556 { 452 {
557 int name[2], rtsig_max, rtsig_nr, events, ready; 453 int name[2], rtsig_max, rtsig_nr, events, ready;
558 size_t len; 454 size_t len;
559 ngx_int_t tested, n, i; 455 ngx_int_t tested, n, i;
560 ngx_err_t err; 456 ngx_err_t err;
561 ngx_event_t *rev, *wev; 457 ngx_event_t *rev, *wev, **queue;
562 ngx_connection_t *c; 458 ngx_connection_t *c;
563 ngx_rtsig_conf_t *rtscf; 459 ngx_rtsig_conf_t *rtscf;
460
461 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
462 "rtsig process overflow");
564 463
565 rtscf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_rtsig_module); 464 rtscf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_rtsig_module);
566 465
567 tested = 0; 466 tested = 0;
568 467
605 break; 504 break;
606 } 505 }
607 506
608 for ( ;; ) { 507 for ( ;; ) {
609 ready = poll(overflow_list, n, 0); 508 ready = poll(overflow_list, n, 0);
509
510 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
511 "rtsig overflow poll:%d", ready);
610 512
611 if (ready == -1) { 513 if (ready == -1) {
612 err = ngx_errno; 514 err = ngx_errno;
613 ngx_log_error((err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT, 515 ngx_log_error((err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT,
614 cycle->log, 0, 516 cycle->log, 0,
624 526
625 if (ready <= 0) { 527 if (ready <= 0) {
626 continue; 528 continue;
627 } 529 }
628 530
629 if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) { 531 ngx_mutex_lock(ngx_posted_events_mutex);
630 return NGX_ERROR;
631 }
632 532
633 for (i = 0; i < n; i++) { 533 for (i = 0; i < n; i++) {
634 c = cycle->files[overflow_list[i].fd]; 534 c = cycle->files[overflow_list[i].fd];
635 535
636 if (c == NULL) { 536 if (c == NULL) {
645 && (overflow_list[i].revents 545 && (overflow_list[i].revents
646 & (POLLIN|POLLERR|POLLHUP|POLLNVAL))) 546 & (POLLIN|POLLERR|POLLHUP|POLLNVAL)))
647 { 547 {
648 tested++; 548 tested++;
649 549
650 if (ngx_threaded) { 550 if ((flags & NGX_POST_THREAD_EVENTS) && !rev->accept) {
651 rev->posted_ready = 1; 551 rev->posted_ready = 1;
652 ngx_post_event(rev);
653 552
654 } else { 553 } else {
655 rev->ready = 1; 554 rev->ready = 1;
656 rev->handler(rev); 555 }
556
557 if (flags & NGX_POST_EVENTS) {
558 queue = (ngx_event_t **) (rev->accept ?
559 &ngx_posted_accept_events : &ngx_posted_events);
560
561 ngx_locked_post_event(rev, queue);
562
563 } else {
564 rev->handler(rev);
657 } 565 }
658 } 566 }
659 567
660 wev = c->write; 568 wev = c->write;
661 569
665 && (overflow_list[i].revents 573 && (overflow_list[i].revents
666 & (POLLOUT|POLLERR|POLLHUP|POLLNVAL))) 574 & (POLLOUT|POLLERR|POLLHUP|POLLNVAL)))
667 { 575 {
668 tested++; 576 tested++;
669 577
670 if (ngx_threaded) { 578 if (flags & NGX_POST_THREAD_EVENTS) {
671 wev->posted_ready = 1; 579 wev->posted_ready = 1;
672 ngx_post_event(wev);
673 580
674 } else { 581 } else {
675 wev->ready = 1; 582 wev->ready = 1;
676 wev->handler(wev); 583 }
584
585 if (flags & NGX_POST_EVENTS) {
586 ngx_locked_post_event(wev, &ngx_posted_events);
587
588 } else {
589 wev->handler(wev);
677 } 590 }
678 } 591 }
679 } 592 }
680 593
681 ngx_mutex_unlock(ngx_posted_events_mutex); 594 ngx_mutex_unlock(ngx_posted_events_mutex);
686 599
687 /* 600 /*
688 * Check the current rt queue length to prevent 601 * Check the current rt queue length to prevent
689 * the new overflow. 602 * the new overflow.
690 * 603 *
691 * Learn the /proc/sys/kernel/rtsig-max value because 604 * learn the "/proc/sys/kernel/rtsig-max" value because
692 * it can be changed since the last checking. 605 * it can be changed since the last checking
693 */ 606 */
694 607
695 name[0] = CTL_KERN; 608 name[0] = CTL_KERN;
696 name[1] = KERN_RTSIGMAX; 609 name[1] = KERN_RTSIGMAX;
697 len = sizeof(rtsig_max); 610 len = sizeof(rtsig_max);
711 "sysctl(KERN_RTSIGNR) failed"); 624 "sysctl(KERN_RTSIGNR) failed");
712 return NGX_ERROR; 625 return NGX_ERROR;
713 } 626 }
714 627
715 /* 628 /*
716 * drain the rt signal queue if the /proc/sys/kernel/rtsig-nr 629 * drain the rt signal queue if the /"proc/sys/kernel/rtsig-nr"
717 * is bigger than 630 * is bigger than
718 * /proc/sys/kernel/rtsig-max / rtsig_overflow_threshold 631 * "/proc/sys/kernel/rtsig-max" / "rtsig_overflow_threshold"
719 */ 632 */
720 633
721 if (rtsig_max / rtscf->overflow_threshold < rtsig_nr) { 634 if (rtsig_max / rtscf->overflow_threshold < rtsig_nr) {
722 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, 635 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
723 "rtsig queue state: %d/%d", 636 "rtsig queue state: %d/%d",
724 rtsig_nr, rtsig_max); 637 rtsig_nr, rtsig_max);
725 while (ngx_rtsig_process_events(cycle) == NGX_OK) { 638 while (ngx_rtsig_process_events(cycle, 0, flags) == NGX_OK)
639 {
726 /* void */ 640 /* void */
727 } 641 }
728 } 642 }
729 643
730 } else { 644 } else {
732 /* 646 /*
733 * Linux has not KERN_RTSIGMAX since 2.6.6-mm2 647 * Linux has not KERN_RTSIGMAX since 2.6.6-mm2
734 * so drain the rt signal queue unconditionally 648 * so drain the rt signal queue unconditionally
735 */ 649 */
736 650
737 while (ngx_rtsig_process_events(cycle) == NGX_OK) { /* void */ } 651 while (ngx_rtsig_process_events(cycle, 0, flags) == NGX_OK) {
652 /* void */
653 }
738 } 654 }
739 655
740 tested = 0; 656 tested = 0;
741 } 657 }
742 } 658 }
743 659
744 if (ngx_posted_events) { 660 if (flags & NGX_UPDATE_TIME) {
745 if (ngx_threaded) { 661 ngx_time_update(0, 0);
746 ngx_wakeup_worker_thread(cycle);
747
748 } else {
749 ngx_event_process_posted(cycle);
750 }
751 } 662 }
752 663
753 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, 664 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
754 "rt signal queue overflow recovered"); 665 "rt signal queue overflow recovered");
755 666