libxtc 0.4.0
Async concurrency for C: Tokio + Seastar + BEAM, in one library
Loading...
Searching...
No Matches
xtc_io.h
1/*-
2 * Copyright (c) 2026, The XTC Project
3 * Use of this source code is governed by the ISC License.
4 *
5 * src/inc/xtc_io.h
6 * The L1 event-notification engine: register interest in fd
7 * readiness, poll for ready events, wake the poller from another
8 * thread.
9 *
10 * Exactly one backend is compiled in per binary (configure-time).
11 * M2 ships poll(2) and epoll; later milestones add io_uring,
12 * kqueue, IOCP, Solaris event ports, and AIX pollset.
13 *
14 * See M2_CLAIMS.md.
15 */
16
17#ifndef XTC_IO_H
18#define XTC_IO_H
19
20#include <stdint.h>
21
22typedef struct xtc_io xtc_io_t;
23
24/*
25 * Event flag bits. Stable across minor versions; new flags appear
26 * at higher bit positions only (PLAN.md (S)18).
27 */
28#define XTC_IO_READABLE 0x01u
29#define XTC_IO_WRITABLE 0x02u
30#define XTC_IO_HUP 0x04u
31#define XTC_IO_ERR 0x08u
32#define XTC_IO_WAKEUP 0x10u /* set on the synthetic event delivered
33 by xtc_io_wakeup; tag is NULL. */
34#define XTC_IO_AIO 0x20u /* set on an async file-I/O completion;
35 tag is the xtc_aio_t's tag. */
36
37typedef struct xtc_io_event {
38 void *tag; /* the value passed at registration; NULL on wakeups */
39 uint32_t flags; /* XTC_IO_* bitset */
41
42/*
43 * Async file I/O. A native completion-based file operation: io_uring
44 * submits IORING_OP_READ/WRITE/FSYNC; kqueue submits POSIX AIO with
45 * SIGEV_KEVENT and reaps EVFILT_AIO; IOCP uses overlapped reads/writes
46 * on the port -- in each case the completion wakes the tagged task. On
47 * a readiness-only backend (epoll, poll, select, event ports, AIX)
48 * xtc_io_aio_submit returns XTC_E_NOSYS and the caller offloads the op
49 * to the blocking pool instead, because a regular file is not pollable.
50 * See xtc_aio(3).
51 */
52enum {
53 XTC_AIO_PREAD = 0,
54 XTC_AIO_PWRITE = 1,
55 XTC_AIO_FSYNC = 2, /* full sync: data + metadata */
56 XTC_AIO_FDATASYNC = 3, /* data only (fsync on macOS, which lacks it) */
57 XTC_AIO_PREADV = 4, /* vectored read (iov/iovcnt) */
58 XTC_AIO_PWRITEV = 5 /* vectored write (iov/iovcnt) */
59};
60typedef struct xtc_aio {
61 int fd;
62 int op; /* XTC_AIO_* */
63 void *buf; /* read/write buffer (scalar ops; NULL for FSYNC/V) */
64 uint32_t len; /* byte count (scalar ops) */
65 int64_t off; /* file offset (ignored for FSYNC) */
66 void *tag; /* woken on completion (an xtc_task_t *) */
67 int done; /* 0 until the completion is reaped */
68 int32_t res; /* bytes transferred, or -errno */
69 /* Vectored ops (PREADV / PWRITEV): iov points at the caller's
70 * iovec array (struct iovec *, kept opaque here to avoid a
71 * <sys/uio.h> dependency in this header) and iovcnt is its count.
72 * Zero/NULL for the scalar and sync ops. */
73 void *iov; /* const struct iovec * */
74 int iovcnt;
75} xtc_aio_t;
76
77/*
78 * PUBLIC: int xtc_io_init __P((xtc_io_t **));
79 * PUBLIC: int xtc_io_fini __P((xtc_io_t *));
80 * PUBLIC: const char *xtc_io_backend_name __P((void));
81 * PUBLIC: int xtc_io_reg_fd __P((xtc_io_t *, int, uint32_t, void *));
82 * PUBLIC: int xtc_io_mod_fd __P((xtc_io_t *, int, uint32_t, void *));
83 * PUBLIC: int xtc_io_del_fd __P((xtc_io_t *, int));
84 * PUBLIC: int xtc_io_poll __P((xtc_io_t *, xtc_io_event_t *, int, int64_t, int *));
85 * PUBLIC: int xtc_io_aio_submit __P((xtc_io_t *, xtc_aio_t *));
86 * PUBLIC: int xtc_io_wakeup __P((xtc_io_t *));
87 */
88
89/* Lifecycle. */
90int xtc_io_init(xtc_io_t **out);
91int xtc_io_fini(xtc_io_t *io);
92const char *xtc_io_backend_name(void);
93
94/* Registration. */
95int xtc_io_reg_fd(xtc_io_t *io, int fd, uint32_t interest, void *tag);
96int xtc_io_mod_fd(xtc_io_t *io, int fd, uint32_t interest, void *tag);
97int xtc_io_del_fd(xtc_io_t *io, int fd);
98
99/*
100 * xtc_io_poll --
101 * Wait for events. On return *n_out holds the number of events
102 * written (0..max).
103 *
104 * timeout_ns:
105 * == 0 -> non-blocking
106 * > 0 -> wait at most that many nanoseconds
107 * < 0 -> wait indefinitely (until an fd becomes ready or
108 * xtc_io_wakeup is called)
109 */
110int xtc_io_poll(xtc_io_t *io, xtc_io_event_t *events, int max,
111 int64_t timeout_ns, int *n_out);
112
113/* Submit an async file op. XTC_OK if queued (the caller parks until
114 * the completion event with tag a->tag arrives, then reads a->res);
115 * XTC_E_NOSYS if the backend has no native file completion (caller
116 * should offload instead). */
117int xtc_io_aio_submit(xtc_io_t *io, xtc_aio_t *a);
118
119/*
120 * xtc_io_wakeup --
121 * From any thread, cause the next (or in-flight) xtc_io_poll on
122 * this io to return. Safe to call concurrently from many threads;
123 * multiple wakeups before the next poll coalesce into one event.
124 */
125int xtc_io_wakeup(xtc_io_t *io);
126
127#endif /* XTC_IO_H */