xtc_svr(3)

---

xtc_svr(3)

gen_server-style request/reply server abstraction

XTC_SVR(3) Library Functions Manual XTC_SVR(3)

xtc_svr_start, xtc_svr_stop, xtc_svr_join, xtc_svr_call, xtc_svr_call_abortable, xtc_svr_cast, xtc_svr_reply, xtc_svr_call_save, xtc_svr_pidgen_server-style request/reply server abstraction

#include <xtc.h>
#include <xtc_orc.h>

int
xtc_svr_start(xtc_loop_t *loop, const xtc_svr_callbacks_t *cb, void *state, const xtc_svr_opts_t *opts, xtc_svr_t **out);

int
xtc_svr_stop(xtc_svr_t *s);

int
xtc_svr_join(xtc_svr_t *s, int64_t timeout_ns);

int
xtc_svr_call(xtc_pid_t target, const void *req, size_t req_size, void **out_reply, size_t *out_size, int64_t timeout_ns);

int
xtc_svr_call_abortable(xtc_pid_t target, const void *req, size_t req_size, void **out_reply, size_t *out_size, int64_t timeout_ns, xtc_abort_token_t *tok);

int
xtc_svr_cast(xtc_pid_t target, const void *msg, size_t size);

int
xtc_svr_reply(xtc_svr_call_t *call, const void *reply, size_t size);

xtc_svr_call_t *
xtc_svr_call_save(const xtc_svr_call_t *call);

xtc_pid_t
xtc_svr_pid(const xtc_svr_t *s);

xtc_svr is the gen_server analog: a long-lived process that handles synchronous calls and asynchronous casts via user-supplied callbacks. Models the OTP gen_server pattern.

(xtc_svr_callbacks_t):

init
Called once at server start. Returns XTC_OK to proceed or any XTC_E_* to abort startup.
handle_call
Invoked on synchronous request from a client. Must call () to satisfy the caller. Return XTC_SVR_CONTINUE or XTC_SVR_STOP.
handle_cast
Asynchronous (no-reply) message.
handle_info
Raw mailbox message (sent via xtc_send(3)), not call/cast .
terminate
Called on graceful shutdown; cleanup hook.

() sends a request and blocks until reply or timeout. In-process callers (from another xtc_proc) route via tag-and-pid through the caller's mailbox; external threads use slot-and-notify. Both paths return the same way.

() is the same call with cooperative cancellation: while it waits for the reply it polls tok (see xtc_sync(3)), and returns XTC_E_ABORTED if the token's source is fired before the reply arrives. Fire the source from a statement timeout or a cancel-request path to deliver a cancel at the next wait point. Cancellation stops only the caller's wait; the server keeps processing the request, and a late reply is discarded.

() fires-and-forgets a message. Returns immediately.

() sent from inside handle_call to satisfy the calling client. Must be called exactly once per call.

() enables a reply (the OTP () pattern). The xtc_svr_call_t passed to handle_call is valid only for that callback. To reply later -- when a batch fills, when other shards answer, when a timer fires -- call xtc_svr_call_save() inside handle_call to obtain a heap-allocated handle that outlives the callback, stash it in the server state, return XTC_SVR_NOREPLY, and call xtc_svr_reply() on the saved handle from any later callback. xtc_svr_reply() frees a saved handle after sending. This is safe for in-proc callers (the reply routes to the caller's mailbox by tag); an off-proc caller must remain blocked in xtc_svr_call() until the deferred reply is sent.

struct kv_state { /* ... */ };

static int my_init(void *st) { /* ... */ return XTC_OK; }

static int
my_call(void *st, const void *req, size_t sz, xtc_svr_call_t *call)
{
    struct kv_state *s = st;
    /* ... compute reply ... */
    xtc_svr_reply(call, reply_buf, reply_sz);
    return XTC_SVR_CONTINUE;
}

xtc_svr_callbacks_t cb = {
    .init = my_init, .handle_call = my_call, /* ... */
};
xtc_svr_t *s;
xtc_svr_start(loop, &cb, &state, NULL, &s);

/* ... */

void *reply; size_t reply_sz;
xtc_svr_call(xtc_svr_pid(s), req, req_sz, &reply, &reply_sz,
             5000LL * 1000 * 1000);

xtc_supervisor(3), xtc_app(3), xtc_proc(3), xtc(7)

Appeared in xtc 0.1.

May 28, 2026 Debian

View the mdoc source