From 0194b1b8a00d6646f03291e6045918aaaf7cfdc4 Mon Sep 17 00:00:00 2001 From: Dirk Engling Date: Mon, 26 Oct 2026 13:35:58 +0100 Subject: Introduce a sub system that can store io cookies for file descriptors, thread safely so --- ot_fdstate.h | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 ot_fdstate.h (limited to 'ot_fdstate.h') diff --git a/ot_fdstate.h b/ot_fdstate.h new file mode 100644 index 0000000..2693a3b --- /dev/null +++ b/ot_fdstate.h @@ -0,0 +1,52 @@ +/* This software was written by Dirk Engling + It is considered beerware. Prost. Skol. Cheers or whatever. + + $id$ */ + +#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); + +/* 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); + +/* Both only valid while the caller holds the descriptor. */ +void *fdstate_cookie(int fd); +void fdstate_set_expiry(int fd, ot_time expiry); + +#endif -- cgit v1.3