commit c7dccaa8e37c5adf45656a93653f4ee7423fb61d
parent 16fd3092d7565eb90f4487e7314d780cec99a67f
Author: Joris Vink <joris@sanctorum.se>
Date: Fri, 23 Jan 2026 22:51:49 +0100
Add worker_no_accept.
This allows you to turn off accepting normal connections on workers
which in turn makes you able to dedicate them to other things.
Like sending python objects from worker A to worker B so B can do the
heavy lifting of things while A keeps on processing HTTP requests.
Diffstat:
4 files changed, 67 insertions(+), 10 deletions(-)
diff --git a/conf/kore.conf.example b/conf/kore.conf.example
@@ -93,6 +93,9 @@ workers 4
# You might have to tweak this number based on your hardware.
#worker_max_connections 512
+# Disable accepting of normal connections on a given worker process.
+#worker_no_accept 2
+
# Limit of maximum open files per worker.
#worker_rlimit_nofiles 768
diff --git a/include/kore/kore.h b/include/kore/kore.h
@@ -472,7 +472,8 @@ struct kore_worker {
pid_t pid;
int pipe[2];
struct connection *msg[2];
- u_int8_t has_lock;
+ int has_lock;
+ int no_accept;
int restarted;
u_int64_t time_locked;
struct kore_route *active_route;
@@ -774,8 +775,9 @@ void kore_worker_reap(void);
int kore_worker_init(void);
void kore_worker_privsep(void);
void kore_worker_started(void);
-void kore_worker_make_busy(void);
void kore_worker_shutdown(void);
+void kore_worker_make_busy(void);
+void kore_worker_no_accept(u_int8_t);
void kore_worker_dispatch_signal(int);
int kore_worker_spawn(u_int16_t, u_int16_t, u_int16_t);
int kore_worker_keymgr_response_verify(struct kore_msg *,
diff --git a/src/config.c b/src/config.c
@@ -84,6 +84,7 @@ static int configure_privsep(char *);
static int configure_logfile(char *);
static int configure_workers(char *);
static int configure_pidfile(char *);
+static int configure_no_accept(char *);
static int configure_rlimit_nofiles(char *);
static int configure_max_connections(char *);
static int configure_accept_threshold(char *);
@@ -235,6 +236,7 @@ static struct {
{ "worker_death_policy", configure_death_policy },
{ "worker_set_affinity", configure_set_affinity },
{ "pidfile", configure_pidfile },
+ { "worker_no_accept", configure_no_accept },
{ "socket_backlog", configure_socket_backlog },
{ "tls_version", configure_tls_version },
{ "tls_cipher", configure_tls_cipher },
@@ -1877,6 +1879,23 @@ configure_pidfile(char *path)
}
static int
+configure_no_accept(char *option)
+{
+ int err, idx;
+
+ idx = kore_strtonum(option, 10, 1, KORE_WORKER_MAX, &err);
+ if (err != KORE_RESULT_OK) {
+ kore_log(LOG_ERR,
+ "bad value for worker_no_accept '%s'", option);
+ return (KORE_RESULT_ERROR);
+ }
+
+ kore_worker_no_accept(idx);
+
+ return (KORE_RESULT_OK);
+}
+
+static int
configure_max_connections(char *option)
{
int err;
diff --git a/src/worker.c b/src/worker.c
@@ -99,6 +99,7 @@ u_int32_t worker_accept_threshold = 16;
u_int32_t worker_rlimit_nofiles = 768;
u_int32_t worker_max_connections = 512;
u_int32_t worker_active_connections = 0;
+u_int8_t worker_no_accept[KORE_WORKER_MAX];
int worker_policy = KORE_WORKER_POLICY_RESTART;
int
@@ -188,6 +189,9 @@ kore_worker_spawn(u_int16_t idx, u_int16_t id, u_int16_t cpu)
int status;
#endif
+ if (idx >= KORE_WORKER_MAX)
+ fatal("%u > KORE_WORKER_MAX", idx);
+
kw = WORKER(idx);
kw->id = id;
kw->cpu = cpu;
@@ -196,6 +200,7 @@ kore_worker_spawn(u_int16_t idx, u_int16_t id, u_int16_t cpu)
kw->ready = 0;
kw->has_lock = 0;
kw->active_route = NULL;
+ kw->no_accept = worker_no_accept[id];
if (socketpair(AF_UNIX, SOCK_STREAM, 0, kw->pipe) == -1)
fatal("socketpair(): %s", errno_s);
@@ -440,6 +445,12 @@ kore_worker_privsep(void)
}
void
+kore_worker_no_accept(u_int8_t idx)
+{
+ worker_no_accept[idx] = 1;
+}
+
+void
kore_worker_entry(struct kore_worker *kw)
{
struct kore_runtime_call *sigcall;
@@ -543,7 +554,8 @@ kore_worker_entry(struct kore_worker *kw)
last_seed = now;
}
- if (!worker->has_lock && accept_avail) {
+ if (worker->no_accept == 0 &&
+ !worker->has_lock && accept_avail) {
if (worker_acceptlock_obtain()) {
accept_avail = 0;
if (had_lock == 0) {
@@ -572,13 +584,15 @@ kore_worker_entry(struct kore_worker *kw)
kore_platform_event_wait(netwait);
now = kore_time_ms();
- if (worker->has_lock)
- worker_acceptlock_release();
+ if (worker->no_accept == 0) {
+ if (worker->has_lock)
+ worker_acceptlock_release();
- if (!worker->has_lock) {
- if (had_lock == 1) {
- had_lock = 0;
- kore_platform_disable_accept();
+ if (!worker->has_lock) {
+ if (had_lock == 1) {
+ had_lock = 0;
+ kore_platform_disable_accept();
+ }
}
}
@@ -618,7 +632,8 @@ kore_worker_entry(struct kore_worker *kw)
kore_curl_do_timeout();
#endif
#if !defined(KORE_NO_HTTP)
- http_process();
+ if (worker->no_accept == 0)
+ http_process();
#endif
#if defined(KORE_USE_PYTHON)
kore_python_coro_run();
@@ -683,6 +698,9 @@ kore_worker_reap(void)
void
kore_worker_make_busy(void)
{
+ if (worker->no_accept)
+ fatal("%s called with no_accept set", __func__);
+
if (worker_count == WORKER_SOLO_COUNT || worker_no_lock == 1)
return;
@@ -943,6 +961,9 @@ worker_reaper(pid_t pid, int status)
static inline void
worker_acceptlock_release(void)
{
+ if (worker->no_accept)
+ fatal("%s called with no_accept set", __func__);
+
if (worker_count == WORKER_SOLO_COUNT || worker_no_lock == 1)
return;
@@ -973,6 +994,9 @@ worker_acceptlock_obtain(void)
{
int r;
+ if (worker->no_accept)
+ fatal("%s called with no_accept set", __func__);
+
if (worker->has_lock == 1)
return (1);
@@ -1004,6 +1028,9 @@ worker_acceptlock_obtain(void)
static int
worker_trylock(void)
{
+ if (worker->no_accept)
+ fatal("%s called with no_accept set", __func__);
+
if (!__sync_bool_compare_and_swap(&(accept_lock->lock), 0, 1))
return (0);
@@ -1015,6 +1042,9 @@ worker_trylock(void)
static void
worker_unlock(void)
{
+ if (worker->no_accept)
+ fatal("%s called with no_accept set", __func__);
+
accept_lock->current = 0;
if (!__sync_bool_compare_and_swap(&(accept_lock->lock), 1, 0))
kore_log(LOG_NOTICE, "worker_unlock(): wasn't locked");
@@ -1023,6 +1053,9 @@ worker_unlock(void)
static void
worker_accept_avail(struct kore_msg *msg, const void *data)
{
+ if (worker->no_accept)
+ fatal("%s called with no_accept set", __func__);
+
accept_avail = 1;
}