comparison src/event/modules/ngx_rtsig_module.c @ 351:af4c6b45a687

nginx-0.0.4-2004-06-10-22:36:57 import
author Igor Sysoev <igor@sysoev.ru>
date Thu, 10 Jun 2004 18:36:57 +0000
parents 7b96b7f8a6af
children 694d7ddc3599
comparison
equal deleted inserted replaced
350:7b96b7f8a6af 351:af4c6b45a687
25 25
26 #endif 26 #endif
27 27
28 28
29 typedef struct { 29 typedef struct {
30 int signo; 30 int signo;
31 ngx_int_t overflow_events;
32 ngx_int_t overflow_test;
33 ngx_int_t overflow_threshold;
31 } ngx_rtsig_conf_t; 34 } ngx_rtsig_conf_t;
32 35
33 36
34 extern ngx_event_module_t ngx_poll_module_ctx; 37 extern ngx_event_module_t ngx_poll_module_ctx;
35 38
42 45
43 static void *ngx_rtsig_create_conf(ngx_cycle_t *cycle); 46 static void *ngx_rtsig_create_conf(ngx_cycle_t *cycle);
44 static char *ngx_rtsig_init_conf(ngx_cycle_t *cycle, void *conf); 47 static char *ngx_rtsig_init_conf(ngx_cycle_t *cycle, void *conf);
45 48
46 49
47 static sigset_t set; 50 static sigset_t set;
48 static ngx_uint_t overflow, current; 51 static ngx_uint_t overflow, overflow_current;
52 static struct pollfd *overflow_list;
49 53
50 54
51 static ngx_str_t rtsig_name = ngx_string("rtsig"); 55 static ngx_str_t rtsig_name = ngx_string("rtsig");
56
57 static ngx_conf_num_bounds_t ngx_overflow_threshold_bounds = {
58 ngx_conf_check_num_bounds, 2, 10
59 };
60
52 61
53 static ngx_command_t ngx_rtsig_commands[] = { 62 static ngx_command_t ngx_rtsig_commands[] = {
54 63
55 {ngx_string("rtsig_signo"), 64 {ngx_string("rtsig_signo"),
56 NGX_EVENT_CONF|NGX_CONF_TAKE1, 65 NGX_EVENT_CONF|NGX_CONF_TAKE1,
57 ngx_conf_set_num_slot, 66 ngx_conf_set_num_slot,
58 0, 67 0,
59 offsetof(ngx_rtsig_conf_t, signo), 68 offsetof(ngx_rtsig_conf_t, signo),
60 NULL}, 69 NULL},
70
71 {ngx_string("rtsig_overflow_events"),
72 NGX_EVENT_CONF|NGX_CONF_TAKE1,
73 ngx_conf_set_num_slot,
74 0,
75 offsetof(ngx_rtsig_conf_t, overflow_events),
76 NULL},
77
78 {ngx_string("rtsig_overflow_test"),
79 NGX_EVENT_CONF|NGX_CONF_TAKE1,
80 ngx_conf_set_num_slot,
81 0,
82 offsetof(ngx_rtsig_conf_t, overflow_test),
83 NULL},
84
85 {ngx_string("rtsig_overflow_threshold"),
86 NGX_EVENT_CONF|NGX_CONF_TAKE1,
87 ngx_conf_set_num_slot,
88 0,
89 offsetof(ngx_rtsig_conf_t, overflow_threshold),
90 &ngx_overflow_threshold_bounds},
61 91
62 ngx_null_command 92 ngx_null_command
63 }; 93 };
64 94
65 95
108 sigaddset(&set, SIGIO); 138 sigaddset(&set, SIGIO);
109 139
110 if (sigprocmask(SIG_BLOCK, &set, NULL) == -1) { 140 if (sigprocmask(SIG_BLOCK, &set, NULL) == -1) {
111 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, 141 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
112 "sigprocmask() failed"); 142 "sigprocmask() failed");
143 return NGX_ERROR;
144 }
145
146 if (overflow_list) {
147 ngx_free(overflow_list);
148 }
149
150 overflow_list = ngx_alloc(sizeof(struct pollfd) * rtscf->overflow_events,
151 cycle->log);
152 if (overflow_list == NULL) {
113 return NGX_ERROR; 153 return NGX_ERROR;
114 } 154 }
115 155
116 ngx_io = ngx_os_io; 156 ngx_io = ngx_os_io;
117 157
337 377
338 rtscf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_rtsig_module); 378 rtscf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_rtsig_module);
339 379
340 if (signo == rtscf->signo || signo == rtscf->signo + 1) { 380 if (signo == rtscf->signo || signo == rtscf->signo + 1) {
341 381
342 if (overflow && (ngx_uint_t) si.si_fd > current) { 382 if (overflow && (ngx_uint_t) si.si_fd > overflow_current) {
343 return NGX_OK; 383 return NGX_OK;
344 } 384 }
345 385
346 /* TODO: old_cycles */ 386 /* TODO: old_cycles */
347 387
439 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, 479 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
440 "sigaction(%d, SIG_DFL) failed", rtscf->signo + 1); 480 "sigaction(%d, SIG_DFL) failed", rtscf->signo + 1);
441 } 481 }
442 482
443 overflow = 1; 483 overflow = 1;
444 current = 0; 484 overflow_current = 0;
445 ngx_event_actions.process = ngx_rtsig_process_overflow; 485 ngx_event_actions.process = ngx_rtsig_process_overflow;
446 486
447 return NGX_OK; 487 return NGX_OK;
448 488
449 } else if (signo != -1) { 489 } else if (signo != -1) {
471 return NGX_OK; 511 return NGX_OK;
472 } 512 }
473 } 513 }
474 514
475 515
516 /* TODO: old cylces */
517
476 static ngx_int_t ngx_rtsig_process_overflow(ngx_cycle_t *cycle) 518 static ngx_int_t ngx_rtsig_process_overflow(ngx_cycle_t *cycle)
477 { 519 {
478 int name[2], len, rtsig_max, rtsig_nr; 520 int name[2], len, rtsig_max, rtsig_nr, events, ready;
479 ngx_uint_t i, n; 521 ngx_int_t tested, n, i;
522 ngx_err_t err;
480 ngx_connection_t *c; 523 ngx_connection_t *c;
481 524 ngx_rtsig_conf_t *rtscf;
482 /* TODO: old cylces */ 525
483 526 rtscf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_rtsig_module);
484 n = 0; 527
485 c = cycle->connections; 528 tested = 0;
486 for (current = 0; current < cycle->connection_n; current++) { 529
487 530 for ( ;; ) {
488 i = current; 531
489 532 n = 0;
490 if (c[i].fd == -1) { 533 while (n < rtscf->overflow_events) {
534
535 if (overflow_current == cycle->connection_n) {
536 break;
537 }
538
539 c = &cycle->connections[overflow_current++];
540
541 if (c->fd == -1) {
542 continue;
543 }
544
545 events = 0;
546
547 if (c->read->active && c->read->event_handler) {
548 events |= POLLIN;
549 }
550
551 if (c->write->active && c->write->event_handler) {
552 events |= POLLOUT;
553 }
554
555 if (events == 0) {
556 continue;
557 }
558
559 overflow_list[n].fd = c->fd;
560 overflow_list[n].events = events;
561 overflow_list[n].revents = 0;
562 n++;
563 }
564
565 if (n == 0) {
566 break;
567 }
568
569 for ( ;; ) {
570 ready = poll(overflow_list, n, 0);
571
572 if (ready == -1) {
573 err = ngx_errno;
574 ngx_log_error((err == NGX_EINTR) ? NGX_LOG_INFO : NGX_LOG_ALERT,
575 cycle->log, 0,
576 "poll() failed while the overflow recover");
577
578 if (err == NGX_EINTR) {
579 continue;
580 }
581 }
582
583 break;
584 }
585
586 if (ready <= 0) {
491 continue; 587 continue;
492 } 588 }
493 589
494 if (c[i].read->active && c[i].read->event_handler) { 590 for (i = 0; i < n; i++) {
495 n++; 591 c = &cycle->connections[overflow_list[i].fd];
496 c[i].read->ready = 1; 592
497 593 if (overflow_list[i].revents & (POLLIN|POLLERR|POLLHUP|POLLNVAL)) {
498 if (!ngx_threaded) { 594 tested++;
499 c[i].read->event_handler(c[i].read); 595 c->read->ready = 1;
500 596
501 } else { 597 if (!ngx_threaded) {
502 if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) { 598 c->read->event_handler(c->read);
503 return NGX_ERROR; 599
600 } else {
601 if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) {
602 return NGX_ERROR;
603 }
604
605 ngx_post_event(c->read);
606 c->read->returned_instance = c->read->instance;
607
608 ngx_mutex_unlock(ngx_posted_events_mutex);
504 } 609 }
505 610 }
506 ngx_post_event(c[i].read); 611
507 612 if (overflow_list[i].revents & (POLLOUT|POLLERR|POLLHUP|POLLNVAL)) {
508 ngx_mutex_unlock(ngx_posted_events_mutex); 613 tested++;
509 } 614 c->write->ready = 1;
510 }
511
512 if (c[i].write->active && c[i].write->event_handler) {
513 n++;
514 c[i].write->ready = 1;
515 615
516 if (!ngx_threaded) { 616 if (!ngx_threaded) {
517 c[i].write->event_handler(c[i].write); 617 c->write->event_handler(c->write);
518 618
519 } else { 619 } else {
520 if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) { 620 if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_ERROR) {
521 return NGX_ERROR; 621 return NGX_ERROR;
522 } 622 }
523 623
524 ngx_post_event(c[i].write); 624 ngx_post_event(c->write);
525 625 c->write->returned_instance = c->write->instance;
526 ngx_mutex_unlock(ngx_posted_events_mutex); 626
527 } 627 ngx_mutex_unlock(ngx_posted_events_mutex);
528 } 628 }
529 629 }
530 if (n && (n % 100 == 0)) { 630 }
631
632 if (tested >= rtscf->overflow_test) {
531 633
532 /* 634 /*
533 * Check the current rt queue length to prevent the new overflow. 635 * Check the current rt queue length to prevent the new overflow.
534 * 636 *
535 * Learn the /proc/sys/kernel/rtsig-max value because 637 * Learn the /proc/sys/kernel/rtsig-max value because
553 "sysctl(KERN_RTSIGNR) failed"); 655 "sysctl(KERN_RTSIGNR) failed");
554 return NGX_ERROR; 656 return NGX_ERROR;
555 } 657 }
556 658
557 /* 659 /*
558 * drain rt signal queue if the /proc/sys/kernel/rtsig-nr 660 * drain rt signal queue if the /proc/sys/kernel/rtsig-nr is bigger
559 * is bigger than "/proc/sys/kernel/rtsig-max / 4" 661 * than "/proc/sys/kernel/rtsig-max / rtsig_overflow_threshold"
560 */ 662 */
561 663
562 if (rtsig_max / 4 < rtsig_nr) { 664 if (rtsig_max / rtscf->overflow_threshold < rtsig_nr) {
563 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, 665 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
564 "rtsig queue state: %d/%d", rtsig_nr, rtsig_max); 666 "rtsig queue state: %d/%d", rtsig_nr, rtsig_max);
565 while (ngx_rtsig_process_events(cycle) == NGX_OK) { /* void */ } 667 while (ngx_rtsig_process_events(cycle) == NGX_OK) { /* void */ }
566 } 668 }
669
670 tested = 0;
567 } 671 }
568 } 672 }
569 673
570 if (!ngx_threaded) { 674 if (!ngx_threaded) {
571 ngx_event_process_posted(cycle); 675 ngx_event_process_posted(cycle);
587 691
588 ngx_test_null(rtscf, ngx_palloc(cycle->pool, sizeof(ngx_rtsig_conf_t)), 692 ngx_test_null(rtscf, ngx_palloc(cycle->pool, sizeof(ngx_rtsig_conf_t)),
589 NGX_CONF_ERROR); 693 NGX_CONF_ERROR);
590 694
591 rtscf->signo = NGX_CONF_UNSET; 695 rtscf->signo = NGX_CONF_UNSET;
696 rtscf->overflow_events = NGX_CONF_UNSET;
697 rtscf->overflow_test = NGX_CONF_UNSET;
698 rtscf->overflow_threshold = NGX_CONF_UNSET;
592 699
593 return rtscf; 700 return rtscf;
594 } 701 }
595 702
596 703
599 ngx_rtsig_conf_t *rtscf = conf; 706 ngx_rtsig_conf_t *rtscf = conf;
600 707
601 /* LinuxThreads use the first 3 RT signals */ 708 /* LinuxThreads use the first 3 RT signals */
602 ngx_conf_init_value(rtscf->signo, SIGRTMIN + 10); 709 ngx_conf_init_value(rtscf->signo, SIGRTMIN + 10);
603 710
711 ngx_conf_init_value(rtscf->overflow_events, 16);
712 ngx_conf_init_value(rtscf->overflow_test, 100);
713 ngx_conf_init_value(rtscf->overflow_threshold, 4);
714
604 return NGX_CONF_OK; 715 return NGX_CONF_OK;
605 } 716 }