615 } |
615 } |
616 |
616 |
617 log_ereport(LOG_DEBUG, "acceptor: %p listener: %p start", acceptor, acceptor->listener); |
617 log_ereport(LOG_DEBUG, "acceptor: %p listener: %p start", acceptor, acceptor->listener); |
618 ws_atomic_inc32(acceptors_running); |
618 ws_atomic_inc32(acceptors_running); |
619 |
619 |
|
620 // in case the system is too busy and we get EMFILE (Too many open files) |
|
621 // we wait for busy_sleep_time seconds |
|
622 // the sleep time is increased after 5 attempts |
|
623 int busy_sleep_time = 5; |
|
624 int sleep_counter = 0; |
|
625 |
620 for (;;) { |
626 for (;;) { |
621 // accept connections |
627 // accept connections |
622 int clientfd; |
628 int clientfd; |
623 socklen_t length = ca_length; |
629 socklen_t length = ca_length; |
624 |
630 |
629 &length); |
635 &length); |
630 log_ereport(LOG_DEBUG, "acceptor: %p listener: %p: accept(): %d", acceptor, acceptor->listener, clientfd); |
636 log_ereport(LOG_DEBUG, "acceptor: %p listener: %p: accept(): %d", acceptor, acceptor->listener, clientfd); |
631 if (clientfd == -1) { |
637 if (clientfd == -1) { |
632 log_ereport(LOG_FAILURE, "accept %s failed: %s", acceptor->ipv6 ? "ipv6" : "ipv4", strerror(errno)); |
638 log_ereport(LOG_FAILURE, "accept %s failed: %s", acceptor->ipv6 ? "ipv6" : "ipv4", strerror(errno)); |
633 |
639 |
|
640 switch(errno) { |
|
641 case EBADF: acceptor->exit = 1; break; |
|
642 case EINTR: continue; |
|
643 case EINVAL: acceptor->exit = 1; break; |
|
644 case EMFILE: { |
|
645 sleep(busy_sleep_time); |
|
646 sleep_counter++; |
|
647 if(sleep_counter >= 5) { |
|
648 sleep_counter = 0; |
|
649 busy_sleep_time += 5; |
|
650 } |
|
651 } |
|
652 } |
|
653 |
634 if(acceptor->exit) { |
654 if(acceptor->exit) { |
635 log_ereport(LOG_VERBOSE, "acceptor thread %p: listener: %p exit", acceptor, acceptor->listener); |
655 log_ereport(LOG_VERBOSE, "acceptor thread %p: listener: %p exit", acceptor, acceptor->listener); |
636 break; |
656 break; |
637 } |
657 } |
|
658 |
|
659 |
|
660 |
638 continue; |
661 continue; |
639 } |
662 } |
640 |
663 |
641 //if(http_listener_apply_keep_alive_settings(listener, clientfd)) { |
664 //if(http_listener_apply_keep_alive_settings(listener, clientfd)) { |
642 // close(clientfd); |
665 // close(clientfd); |
714 if(acceptor_exit || acceptor->exit) { |
737 if(acceptor_exit || acceptor->exit) { |
715 // this acceptor is outdated |
738 // this acceptor is outdated |
716 log_ereport(LOG_VERBOSE, "acceptor thread %p: listener: %p exit", acceptor, acceptor->listener); |
739 log_ereport(LOG_VERBOSE, "acceptor thread %p: listener: %p exit", acceptor, acceptor->listener); |
717 break; |
740 break; |
718 } |
741 } |
|
742 |
|
743 busy_sleep_time = 5; // reset sleep time |
|
744 sleep_counter = 0; |
719 } |
745 } |
720 |
746 |
721 if(ws_atomic_dec32(acceptors_running) == 0) { |
747 if(ws_atomic_dec32(acceptors_running) == 0) { |
722 // notify |
748 // notify |
723 if(listener->shutdown) { |
749 if(listener->shutdown) { |