skip to content
==> include/mesh/chan.h <==
1/* @ajax/mesh-chan: a channel of fixed-size messages between threads, with the
2 * semantics meshd's Rust relied on (std::sync::mpsc):
3 *
4 * - any number of senders, one receiver; messages arrive in send order;
5 * - unbounded (bound 0), or bounded: try_send refuses when full (sync_channel);
6 * - a send fails once the receiver is gone (close_rx); a receive reports
7 *   "disconnected" once every sender is gone and nothing is left;
8 * - receives wait forever, for a timeout (monotonic clock), or not at all.
9 *
10 * Lifetime is a reference count (retain/release): a channel lives until its
11 * last holder lets go, so a reply sent to a requester that already gave up is
12 * just dropped. Messages still queued then are passed to `drop` (when given),
13 * so what they own is freed. */
14#ifndef MESH_CHAN_H
15#define MESH_CHAN_H
16
17#include <stddef.h>
18#include <stdint.h>
19
20typedef struct mesh_chan mesh_chan;
21
22enum {
23    MESH_CHAN_OK = 0,
24    MESH_CHAN_EMPTY = 1,   /* try_recv: nothing queued */
25    MESH_CHAN_TIMEOUT = 2, /* recv: nothing within the timeout */
26    MESH_CHAN_FULL = 3,    /* try_send: a bounded channel is full */
27    MESH_CHAN_CLOSED = -1, /* send: the receiver is gone; recv: every sender is gone and nothing is left */
28};
29
30/* A channel of `item`-byte messages; bound 0: unbounded. One sender and the
31 * receiver are counted at creation; the caller holds one reference. */
32mesh_chan *mesh_chan_new(size_t item, size_t bound, void (*drop)(void *item));
33void mesh_chan_retain(mesh_chan *c);
34void mesh_chan_release(mesh_chan *c);
35
36/* Sender bookkeeping (Rust's Sender clone / drop). */
37void mesh_chan_add_sender(mesh_chan *c);
38void mesh_chan_drop_sender(mesh_chan *c);
39/* The receiver is gone: later sends fail (and queued messages are dropped). */
40void mesh_chan_close_rx(mesh_chan *c);
41
42/* Blocks while a bounded channel is full. */
43int mesh_chan_send(mesh_chan *c, const void *item);
44int mesh_chan_try_send(mesh_chan *c, const void *item);
45/* timeout_ms < 0: wait forever. */
46int mesh_chan_recv(mesh_chan *c, void *out, int64_t timeout_ms);
47int mesh_chan_try_recv(mesh_chan *c, void *out);
48size_t mesh_chan_len(mesh_chan *c);
49
50/* Milliseconds on the monotonic clock (for deadlines). */
51int64_t mesh_mono_ms(void);
52/* Microseconds on the monotonic clock. */
53int64_t mesh_mono_us(void);
54/* Nanoseconds on the monotonic clock (Rust's Instant). */
55int64_t mesh_mono_ns(void);
56/* Sleeps (EINTR resumed). */
57void mesh_sleep_us(int64_t us);
58
59#endif