From 5e86efde052760a53ca92ddd411db095fcf4a970 Mon Sep 17 00:00:00 2001 From: Dirk Engling Date: Mon, 26 Oct 2026 16:37:55 +0100 Subject: Use new fdstate subsystem to store per fd cookie and timeout --- ot_fdstate.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) (limited to 'ot_fdstate.c') diff --git a/ot_fdstate.c b/ot_fdstate.c index 6ddbea3..7f73d3d 100644 --- a/ot_fdstate.c +++ b/ot_fdstate.c @@ -34,8 +34,11 @@ typedef struct { range descriptor is rejected */ #define FD_SLOTS_MAX (1u << 20) -static ot_fdslot *g_slots; -static size_t g_slot_count; +static ot_fdslot *g_slots; +static size_t g_slot_count; +/* Descriptors are handed out lowest first, so a sweep only has to walk as + far as the highest one ever seen rather than the whole table. */ +static _Atomic size_t g_slot_highest; int fdstate_init(void) { struct rlimit limit; @@ -51,6 +54,7 @@ int fdstate_init(void) { } g_slot_count = count; + atomic_store(&g_slot_highest, 0); return 0; } @@ -59,6 +63,7 @@ void fdstate_deinit(void) { munmap(g_slots, g_slot_count * sizeof(ot_fdslot)); g_slots = NULL; g_slot_count = 0; + atomic_store(&g_slot_highest, 0); } size_t fdstate_slots(void) { return g_slot_count; } @@ -76,6 +81,15 @@ uint32_t fdstate_open(int fd, void *cookie, ot_time expiry) { if (!slot) return 0; + { + size_t highest = atomic_load_explicit(&g_slot_highest, memory_order_relaxed); + + while ((size_t)fd > highest && + !atomic_compare_exchange_weak_explicit(&g_slot_highest, &highest, (size_t)fd, memory_order_relaxed, + memory_order_relaxed)) + ; + } + word = atomic_load_explicit(&slot->state, memory_order_relaxed); atomic_store_explicit(&slot->cookie, cookie, memory_order_relaxed); atomic_store_explicit(&slot->expiry, expiry, memory_order_relaxed); @@ -150,6 +164,16 @@ void fdstate_close(int fd) { atomic_store_explicit(&slot->state, FD_WORD(FD_GEN(word) + 1, FD_FREE), memory_order_release); } +int fdstate_next_expired(ot_time now, int *cursor) { + size_t highest = atomic_load_explicit(&g_slot_highest, memory_order_relaxed); + + for (; (size_t)*cursor <= highest; ++*cursor) + if (fdstate_claim_expired(*cursor, now)) + return (*cursor)++; + + return -1; +} + void *fdstate_cookie(int fd) { ot_fdslot *slot = fdstate_slot(fd); -- cgit v1.3