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_export.h"
27
28#include "xtc.h"
29
30/*
31 * Run fn(arg) on a blocking-pool thread and park the calling process
32 * until it completes; fn's return value is stored in *out_result.
33 *
34 * Must be called from within a process / coroutine running on a loop.
35 * Called outside that context (or where the offload cannot be set up)
36 * it runs fn synchronously on the current thread -- always correct,
37 * just not yielding. Returns XTC_OK once fn has run.
38 *
39 * PUBLIC: int xtc_blocking_run __P((int (*)(void *), void *, int *));
40 */
41XTC_API int xtc_blocking_run(int (*fn)(void *), void *arg, int *out_result);
42
43/*
44 * Off-loop variant of xtc_blocking_run for a plain OS thread that is NOT
45 * a libxtc fiber (xtc_self() == none): offload fn(arg) to the pool and
46 * block the CALLING thread on the completion pipe with a real read(2),
47 * instead of parking a fiber (which a bare thread cannot do). fn runs
48 * on a pool worker, not inline on the caller.
49 *
50 * It is still synchronous from the caller's view (it blocks the calling
51 * thread until fn completes) and does NOT shorten any lock held across
52 * the call -- it moves the syscall off the caller thread, it does not
53 * let a non-fiber caller do other work meanwhile. To keep serving
54 * other multiplexed tasks during a blocking call, make those tasks
55 * fibers on a loop and use xtc_blocking_run (which yields). Returns
56 * XTC_E_INVAL if fn is NULL or if called from a fiber/loop process
57 * (use xtc_blocking_run there); on a pool/pipe setup failure it runs fn
58 * inline and returns XTC_OK.
59 *
60 * PUBLIC: int xtc_blocking_run_off_loop __P((int (*)(void *), void *, int *));
61 */
62XTC_API int xtc_blocking_run_off_loop(int (*fn)(void *), void *arg,
63 int *out_result);
64
65/*
66 * Fire-and-forget variant: hand fn(arg) to the offload pool and return
67 * immediately, without waiting for or collecting the result. Never
68 * parks, so it is callable from any context (e.g. prefetch/read-ahead).
69 * The caller owns arg's lifetime until fn runs (or has fn free it);
70 * there is no completion signal.
71 *
72 * PUBLIC: int xtc_blocking_submit __P((int (*)(void *), void *));
73 */
74XTC_API int xtc_blocking_submit(int (*fn)(void *), void *arg);
75
76/*
77 * Pin the pool to a fixed size (worker threads), overriding the
78 * automatic default. Must be called before the first xtc_blocking_run
79 * / xtc_blocking_submit; later calls return XTC_E_INVAL (too late).
80 *
81 * By DEFAULT the pool auto-sizes: it starts with a CPU-scaled number of
82 * workers (max(4, online CPUs), capped at 64) and grows on demand up to
83 * 64 when work queues up faster than idle workers can take it, so the
84 * offload path is not an artificial bottleneck on a large host nor
85 * over-provisioned on a small one. Setting an explicit size disables
86 * the growth and fixes the pool at exactly that many threads.
87 *
88 * PUBLIC: int xtc_blocking_pool_size __P((int));
89 */
90XTC_API int xtc_blocking_pool_size(int nthreads);
91
92/*
93 * Stop the pool, joining its threads. Idempotent; for orderly
94 * shutdown and leak-checked test runs. A new xtc_blocking_run after
95 * shutdown restarts the pool.
96 *
97 * PUBLIC: void xtc_blocking_shutdown __P((void));
98 */
99XTC_API void xtc_blocking_shutdown(void);
100
101#endif /* XTC_BLOCKING_H */