diff options
| author | Dirk Engling <erdgeist@erdgeist.org> | 2026-10-29 00:53:50 +0100 |
|---|---|---|
| committer | Dirk Engling <erdgeist@erdgeist.org> | 2026-10-29 00:53:50 +0100 |
| commit | 0f95c7d1056cab5bd8c6334cf601349ac4631457 (patch) | |
| tree | c7c27709ef3695659ab4b743d7ae359d4ece272b /ot_udp.c | |
| parent | 2812a6795149f68226e940212c511b7c625c81d5 (diff) | |
Revert last wake-up experiment. Having each udp worker wake up once a second to check if the tracker stops is wasteful
Diffstat (limited to 'ot_udp.c')
| -rw-r--r-- | ot_udp.c | 58 |
1 files changed, 35 insertions, 23 deletions
| @@ -9,7 +9,7 @@ | |||
| 9 | #include <stdio.h> | 9 | #include <stdio.h> |
| 10 | #include <stdlib.h> | 10 | #include <stdlib.h> |
| 11 | #include <string.h> | 11 | #include <string.h> |
| 12 | #include <sys/socket.h> | 12 | #include <unistd.h> |
| 13 | 13 | ||
| 14 | /* Opentracker */ | 14 | /* Opentracker */ |
| 15 | #include "ot_ip.h" | 15 | #include "ot_ip.h" |
| @@ -20,16 +20,16 @@ | |||
| 20 | #include "ot_udp.h" | 20 | #include "ot_udp.h" |
| 21 | #include "trackerlogic.h" | 21 | #include "trackerlogic.h" |
| 22 | 22 | ||
| 23 | /* How long a worker may sit in a read before it looks at the running flag */ | 23 | /* One of these per worker, each allocated on its own so that growing the |
| 24 | #define OT_UDP_WORKER_PATIENCE 1 | 24 | array below never moves the one a running worker holds. */ |
| 25 | |||
| 26 | struct udp_worker { | 25 | struct udp_worker { |
| 27 | pthread_t thread; | 26 | pthread_t thread; |
| 28 | int64_t sock; | 27 | int64_t sock; |
| 28 | _Atomic int left; | ||
| 29 | }; | 29 | }; |
| 30 | 30 | ||
| 31 | static struct udp_worker *g_workers; | 31 | static struct udp_worker **g_workers; |
| 32 | static size_t g_worker_count; | 32 | static size_t g_worker_count; |
| 33 | 33 | ||
| 34 | static uint32_t g_rijndael_round_key[44] = {0}; | 34 | static uint32_t g_rijndael_round_key[44] = {0}; |
| 35 | static volatile uint32_t g_key_of_the_hour[2] = {0}; | 35 | static volatile uint32_t g_key_of_the_hour[2] = {0}; |
| @@ -218,7 +218,7 @@ int handle_udp6(int64_t serversocket, struct ot_workstruct *ws) { | |||
| 218 | } | 218 | } |
| 219 | 219 | ||
| 220 | static void *udp_worker(void *args) { | 220 | static void *udp_worker(void *args) { |
| 221 | int64_t sock = (int64_t)args; | 221 | struct udp_worker *me = args; |
| 222 | struct ot_workstruct ws; | 222 | struct ot_workstruct ws; |
| 223 | memset(&ws, 0, sizeof(ws)); | 223 | memset(&ws, 0, sizeof(ws)); |
| 224 | 224 | ||
| @@ -230,7 +230,7 @@ static void *udp_worker(void *args) { | |||
| 230 | #endif | 230 | #endif |
| 231 | 231 | ||
| 232 | while (g_opentracker_running) | 232 | while (g_opentracker_running) |
| 233 | handle_udp6(sock, &ws); | 233 | handle_udp6(me->sock, &ws); |
| 234 | 234 | ||
| 235 | stats_counters_retire(&ws); | 235 | stats_counters_retire(&ws); |
| 236 | 236 | ||
| @@ -239,6 +239,8 @@ static void *udp_worker(void *args) { | |||
| 239 | #ifdef _DEBUG_HTTPERROR | 239 | #ifdef _DEBUG_HTTPERROR |
| 240 | free(ws.debugbuf); | 240 | free(ws.debugbuf); |
| 241 | #endif | 241 | #endif |
| 242 | |||
| 243 | atomic_store(&me->left, 1); | ||
| 242 | return NULL; | 244 | return NULL; |
| 243 | } | 245 | } |
| 244 | 246 | ||
| @@ -248,34 +250,44 @@ void udp_init(void) { | |||
| 248 | } | 250 | } |
| 249 | 251 | ||
| 250 | void udp_worker_install(int64_t sock) { | 252 | void udp_worker_install(int64_t sock) { |
| 251 | struct udp_worker *grown = realloc(g_workers, (g_worker_count + 1) * sizeof(*g_workers)); | 253 | struct udp_worker **grown = realloc(g_workers, (g_worker_count + 1) * sizeof(*g_workers)); |
| 254 | struct udp_worker *worker; | ||
| 252 | 255 | ||
| 253 | if (!grown) { | 256 | if (!grown || !(worker = calloc(1, sizeof(*worker)))) { |
| 254 | fprintf(stderr, "Warning: out of memory installing a udp worker, this socket stays with the workers already running.\n"); | 257 | fprintf(stderr, "Warning: out of memory installing a udp worker, this socket stays with the workers already running.\n"); |
| 258 | g_workers = grown ? grown : g_workers; | ||
| 255 | return; | 259 | return; |
| 256 | } | 260 | } |
| 257 | g_workers = grown; | 261 | g_workers = grown; |
| 262 | worker->sock = sock; | ||
| 258 | 263 | ||
| 259 | #ifdef _DEBUG | 264 | #ifdef _DEBUG |
| 260 | fprintf(stderr, "Installing a worker on udp socket %ld\n", (unsigned long)sock); | 265 | fprintf(stderr, "Installing a worker on udp socket %ld\n", (unsigned long)sock); |
| 261 | #endif | 266 | #endif |
| 262 | socket_set_blocking((int)sock, 1); | 267 | socket_set_blocking((int)sock, 1); |
| 263 | socket_set_timeout((int)sock, OT_UDP_WORKER_PATIENCE); | ||
| 264 | 268 | ||
| 265 | g_workers[g_worker_count].sock = sock; | 269 | if (pthread_create(&worker->thread, NULL, udp_worker, worker)) |
| 266 | if (!pthread_create(&g_workers[g_worker_count].thread, NULL, udp_worker, (void *)sock)) | 270 | free(worker); |
| 267 | ++g_worker_count; | 271 | else |
| 272 | g_workers[g_worker_count++] = worker; | ||
| 268 | } | 273 | } |
| 269 | 274 | ||
| 270 | void udp_workers_deinit(void) { | 275 | void udp_workers_deinit(void) { |
| 271 | size_t i; | 276 | size_t i; |
| 272 | 277 | ||
| 273 | /* The receive timeout bounds this on its own, shutting the socket down | 278 | for (i = 0; i < g_worker_count; ++i) { |
| 274 | cuts it short wherever the platform wakes a blocked reader */ | 279 | struct udp_worker *worker = g_workers[i]; |
| 275 | for (i = 0; i < g_worker_count; ++i) | 280 | |
| 276 | shutdown((int)g_workers[i].sock, SHUT_RD); | 281 | /* Repeated because a signal only interrupts a read already under way: a |
| 277 | for (i = 0; i < g_worker_count; ++i) | 282 | worker that was between two reads when the first one arrived is inside |
| 278 | pthread_join(g_workers[i].thread, NULL); | 283 | the next one by now. */ |
| 284 | while (!atomic_load(&worker->left)) { | ||
| 285 | pthread_kill(worker->thread, OT_SIGNAL_WAKE); | ||
| 286 | usleep(1000); | ||
| 287 | } | ||
| 288 | pthread_join(worker->thread, NULL); | ||
| 289 | free(worker); | ||
| 290 | } | ||
| 279 | 291 | ||
| 280 | free(g_workers); | 292 | free(g_workers); |
| 281 | g_workers = NULL; | 293 | g_workers = NULL; |
