From ad541c67761b8aa6da1566802c347cac4018d0c2 Mon Sep 17 00:00:00 2001 From: Dirk Engling Date: Mon, 2 Nov 2026 20:50:24 +0100 Subject: Move the build sources into src/ --- src/ot_fdstate.h | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 src/ot_fdstate.h (limited to 'src/ot_fdstate.h') diff --git a/src/ot_fdstate.h b/src/ot_fdstate.h new file mode 100644 index 0000000..60fe070 --- /dev/null +++ b/src/ot_fdstate.h @@ -0,0 +1,62 @@ +/* This software was written by Dirk Engling + It is considered beerware. Prost. Skol. Cheers or whatever. */ + +#ifndef OT_FDSTATE_H__ +#define OT_FDSTATE_H__ + +#include + +#include "trackerlogic.h" + +/* What the tracker knows about a file descriptor: who owns it, when it + should be given up on, and whether anyone is working on it right now. + + A descriptor number says nothing about identity, since the kernel hands + the same number out again as soon as it is closed. Every slot therefore + carries a generation that is bumped when the descriptor is given up, and + every caller that was told about a descriptor has to say which generation + it was told about. A caller holding a stale generation is turned away + instead of being handed somebody else's connection. + + The table is sized once from RLIMIT_NOFILE and never moves, so looking a + descriptor up needs no synchronisation at all. */ + +int fdstate_init(void); +void fdstate_deinit(void); +size_t fdstate_slots(void); + +/* Take a freshly accepted descriptor into the table and return the + generation to quote when asking for it back. expiry of 0 never expires. */ +uint32_t fdstate_open(int fd, void *cookie, ot_time expiry); + +/* Which generation a descriptor currently carries, to check an event that + was handed out earlier against the connection living there now. */ +uint32_t fdstate_generation(int fd); + +/* Ask for exclusive use. Returns 0 if the descriptor has been recycled since + generation was handed out, or if somebody else is using it. */ +int fdstate_claim(int fd, uint32_t generation); +void fdstate_release(int fd); + +/* The cleaner's side of the same thing: takes the descriptor only if nobody + is working on it and it really has expired. Never waits. */ +int fdstate_claim_expired(int fd, ot_time now); + +/* Give the descriptor up. The generation is bumped here, which has to happen + before close(2) so that the kernel cannot reissue the number while events + quoting the old generation are still in flight. */ +void fdstate_close(int fd); + +/* Walks the table for descriptors that have expired, handing back one at a + time until it returns -1. The cursor belongs to the caller, so several + sweepers can run without sharing anything. */ +int fdstate_next_expired(ot_time now, int *cursor); + +/* Both only valid while the caller holds the descriptor. */ +void *fdstate_cookie(int fd); + +/* Hand the slot a different cookie, for a connection whose state has moved */ +void fdstate_set_cookie(int fd, void *cookie); +void fdstate_set_expiry(int fd, ot_time expiry); + +#endif -- cgit v1.3