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.
This commit is contained in:
Joris Vink 2015-04-20 15:17:42 +02:00
parent dfea3cf483
commit 4c39ac43fb
3 changed files with 22 additions and 2 deletions

View File

@ -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;

View File

@ -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;

View File

@ -20,6 +20,7 @@
#include <sys/time.h>
#include <sys/resource.h>
#include <fcntl.h>
#include <grp.h>
#include <pwd.h>
#include <signal.h>
@ -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) {