wired
libc-free QUIC/HTTP3 SDK in C for x86_64-linux
Loading...
Searching...
No Matches
srvinbox.h File Reference

SPSC ring for worker-to-worker broadcast handoff. More...

Go to the source code of this file.

Data Structures

struct  wired_srvinbox_slot
 One ring slot: a datagram payload and its length. More...
struct  wired_srvinbox_ring
 A single-producer/single-consumer ring of depth WIRED_SRVINBOX_DEPTH. More...

Macros

#define WIRED_SRVINBOX_DEPTH   4u
 Ring capacity; must stay a power of two (WIRED_SRVINBOX_DEPTH - 1 is used as the index mask).
#define WIRED_SRVINBOX_SLOT_MAX   1200u
 Max payload bytes one slot holds – sized for one QUIC datagram (srvrun's own dg_pending_buf is 1200 bytes; this matches).

Functions

void wired_srvinbox_ring_init (wired_srvinbox_ring *r)
 Zero-initialize r (prod = cons = 0, empty ring).
int wired_srvinbox_push (wired_srvinbox_ring *r, const u8 *data, usz len)
 Push one message (producer side only).
usz wired_srvinbox_pop (wired_srvinbox_ring *r, u8 *out_buf, usz out_cap)
 Pop one message (consumer side only) into out_buf.

Detailed Description

SPSC ring for worker-to-worker broadcast handoff.

One ring carries best-effort datagram-sized messages from exactly one producer worker to exactly one consumer worker; an N-worker mesh is N*N of these (srvrun.c's broadcast registry owns the mesh, this file only owns one ring's push/pop contract).

Same free-running-counter + ACQUIRE/RELEASE + look-then-reload idiom as transport/io/xdp/xskring/xskring.c, specialized to a fixed-size datagram slot instead of a generic descriptor array: push/pop do their own check+write+publish / check+read+release in one call each, since a datagram producer/consumer never needs to split reservation from publication the way the AF_XDP rings do. Unlike xskring's xskring side struct, there is no per-side cached_prod/cached_cons field – push/ pop are stateless across calls, so every full/empty look re-reads the shared prod/cons cell (still just one extra ACQUIRE load in the common case, since the "reload" only ever runs when the first look already showed full/empty).

Function Documentation

◆ wired_srvinbox_pop()

usz wired_srvinbox_pop ( wired_srvinbox_ring * r,
u8 * out_buf,
usz out_cap )

Pop one message (consumer side only) into out_buf.

If the ring looks empty, prod is re-read with ACQUIRE and re-checked once before reporting empty – mirrors xskring_cons_peek's look-then-recheck idiom. out_cap must be >= the popped message's length or nothing is popped (the slot stays queued, so a caller that always passes a WIRED_SRVINBOX_SLOT_MAX buffer never hits this): this SDK's callers all forward straight into a srvrun_queue_datagram-sized buffer, so undersizing is not expected to happen in practice.

Parameters
rring to pop from
out_bufdestination for the payload bytes
out_capcapacity of out_buf
Returns
number of bytes popped (== the message's length), 0 if the ring was empty or out_buf was too small to hold the next message

◆ wired_srvinbox_push()

int wired_srvinbox_push ( wired_srvinbox_ring * r,
const u8 * data,
usz len )

Push one message (producer side only).

If the ring looks full, cons is re-read with ACQUIRE and the fullness re-checked once before dropping – the same look-then-recheck idiom as xskring_prod_reserve, folded into one call since a datagram producer never needs a separate reserve/submit split.

Parameters
rring to push into
datapayload bytes, copied into the slot
lenpayload length; > WIRED_SRVINBOX_SLOT_MAX is rejected (0 returned, nothing sent)
Returns
1 if the message was published, 0 if dropped (ring full after the reload, or len too large)