diff options
| author | Dirk Engling <erdgeist@erdgeist.org> | 2026-10-26 16:37:55 +0100 |
|---|---|---|
| committer | Dirk Engling <erdgeist@erdgeist.org> | 2026-10-26 16:37:55 +0100 |
| commit | 5e86efde052760a53ca92ddd411db095fcf4a970 (patch) | |
| tree | c538485595c26bc7c47ea281667d0652448fddf3 /ot_fdstate.c | |
| parent | 0194b1b8a00d6646f03291e6045918aaaf7cfdc4 (diff) | |
Use new fdstate subsystem to store per fd cookie and timeout
Diffstat (limited to 'ot_fdstate.c')
| -rw-r--r-- | ot_fdstate.c | 28 |
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 | ||
| 37 | static ot_fdslot *g_slots; | 37 | static ot_fdslot *g_slots; |
| 38 | static size_t g_slot_count; | 38 | static 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. */ | ||
| 41 | static _Atomic size_t g_slot_highest; | ||
| 39 | 42 | ||
| 40 | int fdstate_init(void) { | 43 | int 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 | ||
| 64 | size_t fdstate_slots(void) { return g_slot_count; } | 69 | size_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 | ||
| 167 | int 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 | |||
| 153 | void *fdstate_cookie(int fd) { | 177 | void *fdstate_cookie(int fd) { |
| 154 | ot_fdslot *slot = fdstate_slot(fd); | 178 | ot_fdslot *slot = fdstate_slot(fd); |
| 155 | 179 | ||
