# HG changeset patch # User Olaf Wintermann <olaf.wintermann@gmail.com> # Date 1737736978 -3600 # Node ID 3f8c587734aa95d787c121e266c922610e9fbec9 # Parent fed45fc71e7cb11473a010bf22e3cc0a04964439 add error handling in case accept fails in case of EMFILE, sleep for some seconds diff -r fed45fc71e7c -r 3f8c587734aa src/server/daemon/httplistener.c --- a/src/server/daemon/httplistener.c Sat Jan 18 12:21:50 2025 +0100 +++ b/src/server/daemon/httplistener.c Fri Jan 24 17:42:58 2025 +0100 @@ -617,6 +617,12 @@ log_ereport(LOG_DEBUG, "acceptor: %p listener: %p start", acceptor, acceptor->listener); ws_atomic_inc32(acceptors_running); + // in case the system is too busy and we get EMFILE (Too many open files) + // we wait for busy_sleep_time seconds + // the sleep time is increased after 5 attempts + int busy_sleep_time = 5; + int sleep_counter = 0; + for (;;) { // accept connections int clientfd; @@ -631,10 +637,27 @@ if (clientfd == -1) { log_ereport(LOG_FAILURE, "accept %s failed: %s", acceptor->ipv6 ? "ipv6" : "ipv4", strerror(errno)); + switch(errno) { + case EBADF: acceptor->exit = 1; break; + case EINTR: continue; + case EINVAL: acceptor->exit = 1; break; + case EMFILE: { + sleep(busy_sleep_time); + sleep_counter++; + if(sleep_counter >= 5) { + sleep_counter = 0; + busy_sleep_time += 5; + } + } + } + if(acceptor->exit) { log_ereport(LOG_VERBOSE, "acceptor thread %p: listener: %p exit", acceptor, acceptor->listener); break; } + + + continue; } @@ -716,6 +739,9 @@ log_ereport(LOG_VERBOSE, "acceptor thread %p: listener: %p exit", acceptor, acceptor->listener); break; } + + busy_sleep_time = 5; // reset sleep time + sleep_counter = 0; } if(ws_atomic_dec32(acceptors_running) == 0) {