summaryrefslogtreecommitdiff
path: root/src/ot_fdstate.h
diff options
context:
space:
mode:
authorDirk Engling <erdgeist@erdgeist.org>2026-11-02 20:50:24 +0100
committerDirk Engling <erdgeist@erdgeist.org>2026-11-02 21:14:02 +0100
commitad541c67761b8aa6da1566802c347cac4018d0c2 (patch)
treea9166fa9d349911d69a6948e53b05344dcc348a0 /src/ot_fdstate.h
parentc679ff8a3b1418a5960cc49ba6458a0007df54fa (diff)
Move the build sources into src/
Diffstat (limited to 'src/ot_fdstate.h')
-rw-r--r--src/ot_fdstate.h62
1 files changed, 62 insertions, 0 deletions
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 @@
1/* This software was written by Dirk Engling <erdgeist@erdgeist.org>
2 It is considered beerware. Prost. Skol. Cheers or whatever. */
3
4#ifndef OT_FDSTATE_H__
5#define OT_FDSTATE_H__
6
7#include <stdint.h>
8
9#include "trackerlogic.h"
10
11/* What the tracker knows about a file descriptor: who owns it, when it
12 should be given up on, and whether anyone is working on it right now.
13
14 A descriptor number says nothing about identity, since the kernel hands
15 the same number out again as soon as it is closed. Every slot therefore
16 carries a generation that is bumped when the descriptor is given up, and
17 every caller that was told about a descriptor has to say which generation
18 it was told about. A caller holding a stale generation is turned away
19 instead of being handed somebody else's connection.
20
21 The table is sized once from RLIMIT_NOFILE and never moves, so looking a
22 descriptor up needs no synchronisation at all. */
23
24int fdstate_init(void);
25void fdstate_deinit(void);
26size_t fdstate_slots(void);
27
28/* Take a freshly accepted descriptor into the table and return the
29 generation to quote when asking for it back. expiry of 0 never expires. */
30uint32_t fdstate_open(int fd, void *cookie, ot_time expiry);
31
32/* Which generation a descriptor currently carries, to check an event that
33 was handed out earlier against the connection living there now. */
34uint32_t fdstate_generation(int fd);
35
36/* Ask for exclusive use. Returns 0 if the descriptor has been recycled since
37 generation was handed out, or if somebody else is using it. */
38int fdstate_claim(int fd, uint32_t generation);
39void fdstate_release(int fd);
40
41/* The cleaner's side of the same thing: takes the descriptor only if nobody
42 is working on it and it really has expired. Never waits. */
43int fdstate_claim_expired(int fd, ot_time now);
44
45/* Give the descriptor up. The generation is bumped here, which has to happen
46 before close(2) so that the kernel cannot reissue the number while events
47 quoting the old generation are still in flight. */
48void fdstate_close(int fd);
49
50/* Walks the table for descriptors that have expired, handing back one at a
51 time until it returns -1. The cursor belongs to the caller, so several
52 sweepers can run without sharing anything. */
53int fdstate_next_expired(ot_time now, int *cursor);
54
55/* Both only valid while the caller holds the descriptor. */
56void *fdstate_cookie(int fd);
57
58/* Hand the slot a different cookie, for a connection whose state has moved */
59void fdstate_set_cookie(int fd, void *cookie);
60void fdstate_set_expiry(int fd, ot_time expiry);
61
62#endif