libxtc 0.4.0
Async concurrency for C: Tokio + Seastar + BEAM, in one library
Loading...
Searching...
No Matches
xtc_blocking.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_blocking.h
6 * Offload blocking work to a thread pool, parking the calling
7 * process instead of blocking the loop.
8 *
9 * A loop thread must never block in a syscall: doing so stalls
10 * every other process sharing that loop. But some work is
11 * unavoidably blocking -- file reads and fsync (regular files are
12 * not pollable), getaddrinfo, third-party libraries. xtc_blocking
13 * runs such a call on a dedicated pool thread and parks the
14 * calling process until it finishes, so the loop keeps running
15 * other work meanwhile.
16 *
17 * The wakeup reuses the runtime's existing machinery: the pool
18 * thread signals completion on a pipe the calling process waits on
19 * with xtc_proc_wait_fd, so no new scheduler integration is
20 * needed.
21 */
22
23#ifndef XTC_BLOCKING_H
24#define XTC_BLOCKING_H
25
26#include "xtc.h"
27
28/*
29 * Run fn(arg) on a blocking-pool thread and park the calling process
30 * until it completes; fn's return value is stored in *out_result.
31 *
32 * Must be called from within a process / coroutine running on a loop.
33 * Called outside that context (or where the offload cannot be set up)
34 * it runs fn synchronously on the current thread -- always correct,
35 * just not yielding. Returns XTC_OK once fn has run.
36 *
37 * PUBLIC: int xtc_blocking_run __P((int (*)(void *), void *, int *));
38 */
39int xtc_blocking_run(int (*fn)(void *), void *arg, int *out_result);
40
41/*
42 * Fire-and-forget variant: hand fn(arg) to the offload pool and return
43 * immediately, without waiting for or collecting the result. Never
44 * parks, so it is callable from any context (e.g. prefetch/read-ahead).
45 * The caller owns arg's lifetime until fn runs (or has fn free it);
46 * there is no completion signal.
47 *
48 * PUBLIC: int xtc_blocking_submit __P((int (*)(void *), void *));
49 */
50int xtc_blocking_submit(int (*fn)(void *), void *arg);
51
52/*
53 * Pin the pool to a fixed size (worker threads), overriding the
54 * automatic default. Must be called before the first xtc_blocking_run
55 * / xtc_blocking_submit; later calls return XTC_E_INVAL (too late).
56 *
57 * By DEFAULT the pool auto-sizes: it starts with a CPU-scaled number of
58 * workers (max(4, online CPUs), capped at 64) and grows on demand up to
59 * 64 when work queues up faster than idle workers can take it, so the
60 * offload path is not an artificial bottleneck on a large host nor
61 * over-provisioned on a small one. Setting an explicit size disables
62 * the growth and fixes the pool at exactly that many threads.
63 *
64 * PUBLIC: int xtc_blocking_pool_size __P((int));
65 */
66int xtc_blocking_pool_size(int nthreads);
67
68/*
69 * Stop the pool, joining its threads. Idempotent; for orderly
70 * shutdown and leak-checked test runs. A new xtc_blocking_run after
71 * shutdown restarts the pool.
72 *
73 * PUBLIC: void xtc_blocking_shutdown __P((void));
74 */
75void xtc_blocking_shutdown(void);
76
77#endif /* XTC_BLOCKING_H */