diff options
| author | Dirk Engling <erdgeist@erdgeist.org> | 2026-11-01 00:53:53 +0100 |
|---|---|---|
| committer | Dirk Engling <erdgeist@erdgeist.org> | 2026-11-01 00:53:53 +0100 |
| commit | af0f2cb1be5aa10bb6a4bdd9f7ef4aa3950ecb31 (patch) | |
| tree | bd366224016709d65bbb0b8fbc3148c29719e8c4 /ot_udp.c | |
| parent | b7d9dc14eb560b1d19f506610535815f29085579 (diff) | |
Generalize the worker setup/runloop/teardown logic by adding a smol ot_worker helper
Diffstat (limited to 'ot_udp.c')
| -rw-r--r-- | ot_udp.c | 69 |
1 files changed, 5 insertions, 64 deletions
| @@ -16,21 +16,11 @@ | |||
| 16 | #include "ot_random.h" | 16 | #include "ot_random.h" |
| 17 | #include "ot_rijndael.h" | 17 | #include "ot_rijndael.h" |
| 18 | #include "ot_socket.h" | 18 | #include "ot_socket.h" |
| 19 | #include "ot_worker.h" | ||
| 19 | #include "ot_stats.h" | 20 | #include "ot_stats.h" |
| 20 | #include "ot_udp.h" | 21 | #include "ot_udp.h" |
| 21 | #include "trackerlogic.h" | 22 | #include "trackerlogic.h" |
| 22 | 23 | ||
| 23 | /* One of these per worker, each allocated on its own so that growing the | ||
| 24 | array below never moves the one a running worker holds. */ | ||
| 25 | struct udp_worker { | ||
| 26 | pthread_t thread; | ||
| 27 | int64_t sock; | ||
| 28 | _Atomic int left; | ||
| 29 | }; | ||
| 30 | |||
| 31 | static struct udp_worker **g_workers; | ||
| 32 | static size_t g_worker_count; | ||
| 33 | |||
| 34 | static uint32_t g_rijndael_round_key[44] = {0}; | 24 | static uint32_t g_rijndael_round_key[44] = {0}; |
| 35 | static volatile uint32_t g_key_of_the_hour[2] = {0}; | 25 | static volatile uint32_t g_key_of_the_hour[2] = {0}; |
| 36 | static volatile ot_time g_hour_of_the_key; | 26 | static volatile ot_time g_hour_of_the_key; |
| @@ -217,22 +207,9 @@ int handle_udp6(int64_t serversocket, struct ot_workstruct *ws) { | |||
| 217 | return 1; | 207 | return 1; |
| 218 | } | 208 | } |
| 219 | 209 | ||
| 220 | static void *udp_worker(void *args) { | 210 | static void udp_run(struct ot_worker *me) { |
| 221 | struct udp_worker *me = args; | ||
| 222 | struct ot_workstruct ws; | ||
| 223 | |||
| 224 | if (workstruct_init(&ws) == -1) { | ||
| 225 | fprintf(stderr, "Warning: a udp worker could not get its buffers and will not run.\n"); | ||
| 226 | atomic_store(&me->left, 1); | ||
| 227 | return NULL; | ||
| 228 | } | ||
| 229 | |||
| 230 | while (g_opentracker_running) | 211 | while (g_opentracker_running) |
| 231 | handle_udp6(me->sock, &ws); | 212 | handle_udp6(me->sock, &me->ws); |
| 232 | |||
| 233 | workstruct_deinit(&ws); | ||
| 234 | atomic_store(&me->left, 1); | ||
| 235 | return NULL; | ||
| 236 | } | 213 | } |
| 237 | 214 | ||
| 238 | void udp_init(void) { | 215 | void udp_init(void) { |
| @@ -241,47 +218,11 @@ void udp_init(void) { | |||
| 241 | } | 218 | } |
| 242 | 219 | ||
| 243 | void udp_worker_install(int64_t sock) { | 220 | void udp_worker_install(int64_t sock) { |
| 244 | struct udp_worker **grown = realloc(g_workers, (g_worker_count + 1) * sizeof(*g_workers)); | ||
| 245 | struct udp_worker *worker; | ||
| 246 | |||
| 247 | if (!grown || !(worker = calloc(1, sizeof(*worker)))) { | ||
| 248 | fprintf(stderr, "Warning: out of memory installing a udp worker, this socket stays with the workers already running.\n"); | ||
| 249 | g_workers = grown ? grown : g_workers; | ||
| 250 | return; | ||
| 251 | } | ||
| 252 | g_workers = grown; | ||
| 253 | worker->sock = sock; | ||
| 254 | |||
| 255 | #ifdef _DEBUG | 221 | #ifdef _DEBUG |
| 256 | fprintf(stderr, "Installing a worker on udp socket %ld\n", (unsigned long)sock); | 222 | fprintf(stderr, "Installing a worker on udp socket %ld\n", (unsigned long)sock); |
| 257 | #endif | 223 | #endif |
| 258 | socket_set_blocking((int)sock, 1); | 224 | socket_set_blocking((int)sock, 1); |
| 259 | 225 | ||
| 260 | if (pthread_create(&worker->thread, NULL, udp_worker, worker)) | 226 | if (worker_start(udp_run, sock) == -1) |
| 261 | free(worker); | 227 | fprintf(stderr, "Warning: could not install a udp worker, this socket stays with the workers already running.\n"); |
| 262 | else | ||
| 263 | g_workers[g_worker_count++] = worker; | ||
| 264 | } | 228 | } |
| 265 | |||
| 266 | void udp_workers_deinit(void) { | ||
| 267 | size_t i; | ||
| 268 | |||
| 269 | for (i = 0; i < g_worker_count; ++i) { | ||
| 270 | struct udp_worker *worker = g_workers[i]; | ||
| 271 | |||
| 272 | /* Repeated because a signal only interrupts a read already under way: a | ||
| 273 | worker that was between two reads when the first one arrived is inside | ||
| 274 | the next one by now. */ | ||
| 275 | while (!atomic_load(&worker->left)) { | ||
| 276 | pthread_kill(worker->thread, OT_SIGNAL_WAKE); | ||
| 277 | usleep(1000); | ||
| 278 | } | ||
| 279 | pthread_join(worker->thread, NULL); | ||
| 280 | free(worker); | ||
| 281 | } | ||
| 282 | |||
| 283 | free(g_workers); | ||
| 284 | g_workers = NULL; | ||
| 285 | g_worker_count = 0; | ||
| 286 | } | ||
| 287 | |||
