From 4c39ac43fbbaf67a280d31372ddbe1f087429d11 Mon Sep 17 00:00:00 2001 From: Joris Vink Date: Mon, 20 Apr 2015 15:17:42 +0200 Subject: [PATCH] Properly deal with accept() failing. In cases where accept() failed Kore would not relinquish the lock towards other worker processes. This becomes evident when dealing with a high number of concurrent connections to the point the fd table gets full. In this scenario the worker with the full fd table will spin on attempt to accept newer connections. As a bonus, Kore now has allows exactly up to worker_max_connections of connections per worker before no longer attempting to grab the accept lock. --- src/bsd.c | 6 +++++- src/linux.c | 6 +++++- src/worker.c | 12 ++++++++++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/bsd.c b/src/bsd.c index a70e818..1501de1 100644 --- a/src/bsd.c +++ b/src/bsd.c @@ -153,7 +153,11 @@ kore_platform_event_wait(u_int64_t timer) while (worker_active_connections < worker_max_connections) { - kore_connection_accept(l, &c); + if (!kore_connection_accept(l, &c)) { + r = 1; + break; + } + if (c == NULL) break; diff --git a/src/linux.c b/src/linux.c index bbd5987..47f8f11 100644 --- a/src/linux.c +++ b/src/linux.c @@ -130,7 +130,11 @@ kore_platform_event_wait(u_int64_t timer) while (worker_active_connections < worker_max_connections) { - kore_connection_accept(l, &c); + if (!kore_connection_accept(l, &c)) { + r = 1; + break; + } + if (c == NULL) break; diff --git a/src/worker.c b/src/worker.c index 4d70380..6730a1e 100644 --- a/src/worker.c +++ b/src/worker.c @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -182,6 +183,7 @@ kore_worker_dispatch_signal(int sig) void kore_worker_entry(struct kore_worker *kw) { + size_t fd; struct rlimit rl; char buf[16]; struct connection *c, *cnext; @@ -197,6 +199,16 @@ kore_worker_entry(struct kore_worker *kw) fatal("cannot chdir(): %s", errno_s); } + if (getrlimit(RLIMIT_NOFILE, &rl) == -1) { + kore_log(LOG_WARNING, "getrlimit(RLIMIT_NOFILE): %s", errno_s); + } else { + for (fd = 0; fd < rl.rlim_cur; fd++) { + if (fcntl(fd, F_GETFD, NULL) != -1) { + worker_rlimit_nofiles++; + } + } + } + rl.rlim_cur = worker_rlimit_nofiles; rl.rlim_max = worker_rlimit_nofiles; if (setrlimit(RLIMIT_NOFILE, &rl) == -1) {