summaryrefslogtreecommitdiff
path: root/ot_fdstate.c
diff options
context:
space:
mode:
authorDirk Engling <erdgeist@erdgeist.org>2026-10-26 16:37:55 +0100
committerDirk Engling <erdgeist@erdgeist.org>2026-10-26 16:37:55 +0100
commit5e86efde052760a53ca92ddd411db095fcf4a970 (patch)
treec538485595c26bc7c47ea281667d0652448fddf3 /ot_fdstate.c
parent0194b1b8a00d6646f03291e6045918aaaf7cfdc4 (diff)
Use new fdstate subsystem to store per fd cookie and timeout
Diffstat (limited to 'ot_fdstate.c')
-rw-r--r--ot_fdstate.c28
1 files changed, 26 insertions, 2 deletions
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 {
34 range descriptor is rejected */ 34 range descriptor is rejected */
35#define FD_SLOTS_MAX (1u << 20) 35#define FD_SLOTS_MAX (1u << 20)
36 36
37static ot_fdslot *g_slots; 37static ot_fdslot *g_slots;
38static size_t g_slot_count; 38static size_t g_slot_count;
39/* Descriptors are handed out lowest first, so a sweep only has to walk as
40 far as the highest one ever seen rather than the whole table. */
41static _Atomic size_t g_slot_highest;
39 42
40int fdstate_init(void) { 43int fdstate_init(void) {
41 struct rlimit limit; 44 struct rlimit limit;
@@ -51,6 +54,7 @@ int fdstate_init(void) {
51 } 54 }
52 55
53 g_slot_count = count; 56 g_slot_count = count;
57 atomic_store(&g_slot_highest, 0);
54 return 0; 58 return 0;
55} 59}
56 60
@@ -59,6 +63,7 @@ void fdstate_deinit(void) {
59 munmap(g_slots, g_slot_count * sizeof(ot_fdslot)); 63 munmap(g_slots, g_slot_count * sizeof(ot_fdslot));
60 g_slots = NULL; 64 g_slots = NULL;
61 g_slot_count = 0; 65 g_slot_count = 0;
66 atomic_store(&g_slot_highest, 0);
62} 67}
63 68
64size_t fdstate_slots(void) { return g_slot_count; } 69size_t fdstate_slots(void) { return g_slot_count; }
@@ -76,6 +81,15 @@ uint32_t fdstate_open(int fd, void *cookie, ot_time expiry) {
76 if (!slot) 81 if (!slot)
77 return 0; 82 return 0;
78 83
84 {
85 size_t highest = atomic_load_explicit(&g_slot_highest, memory_order_relaxed);
86
87 while ((size_t)fd > highest &&
88 !atomic_compare_exchange_weak_explicit(&g_slot_highest, &highest, (size_t)fd, memory_order_relaxed,
89 memory_order_relaxed))
90 ;
91 }
92
79 word = atomic_load_explicit(&slot->state, memory_order_relaxed); 93 word = atomic_load_explicit(&slot->state, memory_order_relaxed);
80 atomic_store_explicit(&slot->cookie, cookie, memory_order_relaxed); 94 atomic_store_explicit(&slot->cookie, cookie, memory_order_relaxed);
81 atomic_store_explicit(&slot->expiry, expiry, memory_order_relaxed); 95 atomic_store_explicit(&slot->expiry, expiry, memory_order_relaxed);
@@ -150,6 +164,16 @@ void fdstate_close(int fd) {
150 atomic_store_explicit(&slot->state, FD_WORD(FD_GEN(word) + 1, FD_FREE), memory_order_release); 164 atomic_store_explicit(&slot->state, FD_WORD(FD_GEN(word) + 1, FD_FREE), memory_order_release);
151} 165}
152 166
167int fdstate_next_expired(ot_time now, int *cursor) {
168 size_t highest = atomic_load_explicit(&g_slot_highest, memory_order_relaxed);
169
170 for (; (size_t)*cursor <= highest; ++*cursor)
171 if (fdstate_claim_expired(*cursor, now))
172 return (*cursor)++;
173
174 return -1;
175}
176
153void *fdstate_cookie(int fd) { 177void *fdstate_cookie(int fd) {
154 ot_fdslot *slot = fdstate_slot(fd); 178 ot_fdslot *slot = fdstate_slot(fd);
155 179