xtc_blocking(3)
---xtc_blocking(3)
offload blocking work to a thread pool without stalling the loop
| XTC_BLOCKING(3) | Library Functions Manual | XTC_BLOCKING(3) |
NAME
xtc_blocking_run,
xtc_blocking_submit,
xtc_blocking_pool_size,
xtc_blocking_shutdown —
offload blocking work to a thread pool without stalling the
loop
SYNOPSIS
#include <xtc.h>
#include <xtc_blocking.h>
int
xtc_blocking_run(int
(*fn)(void *), void
*arg, int
*out_result);
int
xtc_blocking_submit(int
(*fn)(void *), void
*arg);
int
xtc_blocking_pool_size(int
nthreads);
void
xtc_blocking_shutdown(void);
DESCRIPTION
A loop thread must never block in a syscall: doing so stalls every
other process sharing that loop. Some work is unavoidably blocking however
-- reads and fsync(2) on regular files (which are not
pollable), getaddrinfo(3), and third-party libraries. The
xtc_blocking facility runs such a call on a
dedicated pool thread and parks the calling process until it finishes, so
the loop keeps running other work meanwhile. The wakeup reuses the runtime's
existing machinery: the pool thread signals completion on a pipe the calling
process waits on with
xtc_proc_wait_fd(),
so no new scheduler integration is required.
xtc_blocking_run()
runs fn(arg) on a pool thread
and parks the caller until it completes, storing fn's
return value in *out_result. It must be called from
within a process or coroutine running on a loop; called outside that context
(or where the offload cannot be set up) it runs fn
synchronously on the current thread -- always correct, just not
yielding.
xtc_blocking_submit()
is the fire-and-forget variant: it hands
fn(arg) to the pool and returns
immediately without waiting for or collecting the result. It never parks, so
it is callable from any context (for example prefetch or read-ahead). The
caller owns arg's lifetime until
fn runs (or has fn free it);
there is no completion signal.
xtc_blocking_pool_size()
pins the pool to a fixed nthreads worker threads,
overriding the automatic default. It must be called before the first
xtc_blocking_run() or
xtc_blocking_submit(); a later call returns
XTC_E_INVAL (too late). By default the pool
auto-sizes: it starts with a CPU-scaled worker count
(max(4,
, online CPUs), capped at 64) and grows on demand up
to 64 when work queues faster than idle workers can take it, so the offload
path is neither an artificial bottleneck on a large host nor
over-provisioned on a small one. An explicit size disables growth and fixes
the pool at exactly that many threads.
xtc_blocking_shutdown()
stops the pool, joining its threads. It is idempotent, for orderly shutdown
and leak-checked test runs. A new xtc_blocking_run()
after shutdown restarts the pool.
RETURN VALUES
xtc_blocking_run() returns
XTC_OK once fn has run.
xtc_blocking_submit() returns
XTC_OK if the work was enqueued, or a negative
XTC_E_* code.
xtc_blocking_pool_size() returns
XTC_OK, or XTC_E_INVAL if
called after the pool has started.
SEE ALSO
AUTHORS
The XTC Project.
| July 3, 2026 | Debian |