From 772873104658182a5b76f5c0eed76047c62c6651 Mon Sep 17 00:00:00 2001 From: Dirk Engling Date: Wed, 28 Oct 2026 23:31:07 +0100 Subject: With more workers blockingly waiting on udp sockets, we need to keep track of all sockets to shut them down on exit --- ot_udp.c | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) (limited to 'ot_udp.c') diff --git a/ot_udp.c b/ot_udp.c index 87741da..7aa0e61 100644 --- a/ot_udp.c +++ b/ot_udp.c @@ -9,6 +9,7 @@ #include #include #include +#include /* Opentracker */ #include "ot_ip.h" @@ -19,6 +20,17 @@ #include "ot_udp.h" #include "trackerlogic.h" +/* How long a worker may sit in a read before it looks at the running flag */ +#define OT_UDP_WORKER_PATIENCE 1 + +struct udp_worker { + pthread_t thread; + int64_t sock; +}; + +static struct udp_worker *g_workers; +static size_t g_worker_count; + static uint32_t g_rijndael_round_key[44] = {0}; static volatile uint32_t g_key_of_the_hour[2] = {0}; static volatile ot_time g_hour_of_the_key; @@ -236,11 +248,37 @@ void udp_init(void) { } void udp_worker_install(int64_t sock) { - pthread_t thread_id; + struct udp_worker *grown = realloc(g_workers, (g_worker_count + 1) * sizeof(*g_workers)); + + if (!grown) { + fprintf(stderr, "Warning: out of memory installing a udp worker, this socket stays with the workers already running.\n"); + return; + } + g_workers = grown; #ifdef _DEBUG fprintf(stderr, "Installing a worker on udp socket %ld\n", (unsigned long)sock); #endif - pthread_create(&thread_id, NULL, udp_worker, (void *)sock); + socket_set_blocking((int)sock, 1); + socket_set_timeout((int)sock, OT_UDP_WORKER_PATIENCE); + + g_workers[g_worker_count].sock = sock; + if (!pthread_create(&g_workers[g_worker_count].thread, NULL, udp_worker, (void *)sock)) + ++g_worker_count; +} + +void udp_workers_deinit(void) { + size_t i; + + /* The receive timeout bounds this on its own, shutting the socket down + cuts it short wherever the platform wakes a blocked reader */ + for (i = 0; i < g_worker_count; ++i) + shutdown((int)g_workers[i].sock, SHUT_RD); + for (i = 0; i < g_worker_count; ++i) + pthread_join(g_workers[i].thread, NULL); + + free(g_workers); + g_workers = NULL; + g_worker_count = 0; } -- cgit v1.3