skip to content
==> include/mesh/reply.h <==
1/* @ajax/mesh-reply: one-shot replies, as meshd's Rust used a Sender<Result<..>>
2 * per request (shared.rs Reply, TaskReply, HttpReply).
3 *
4 * A reply is a mesh_chan of one mesh_result. The requester makes it, hands a
5 * sender reference to whoever answers (mesh_reply_sender), waits with a
6 * timeout, and releases its own reference. The answerer sends once
7 * (mesh_reply_send and friends consume its reference) or drops it unanswered
8 * (mesh_reply_drop), which the waiter sees at once as MESH_CHAN_CLOSED. A
9 * reply that arrives after the waiter gave up is freed with the channel. */
10#ifndef MESH_REPLY_H
11#define MESH_REPLY_H
12
13#include "mesh/chan.h"
14
15#include <stdbool.h>
16#include <stddef.h>
17#include <stdint.h>
18
19/* Ok(text) / Ok(value) / Ok(bytes), or Err(text). Owns text and bytes. */
20typedef struct {
21    bool ok;
22    uint32_t value;
23    char *text;     /* the Ok text (Reply), or the error; NULL when neither */
24    uint8_t *bytes; /* the Ok bytes (HttpReply) */
25    size_t len;
26    void *ptr;                   /* any other Ok payload (an inventory, a view), freed by ptr_free */
27    void (*ptr_free)(void *ptr);
28} mesh_result;
29
30typedef mesh_chan mesh_reply;
31
32mesh_reply *mesh_reply_new(void);
33/* The requester's handle for an answerer (retained; the answerer consumes it). */
34mesh_reply *mesh_reply_sender(mesh_reply *r);
35/* A second answerer handle (Rust's Sender::clone). */
36mesh_reply *mesh_reply_clone(mesh_reply *r);
37
38/* Answer and let go (r may be NULL: nobody waits). Each takes ownership of nothing but r. */
39void mesh_reply_send(mesh_reply *r, mesh_result res); /* takes res's text and bytes */
40void mesh_reply_ok(mesh_reply *r, const char *text);
41void mesh_reply_okf(mesh_reply *r, const char *fmt, ...) __attribute__((format(printf, 2, 3)));
42void mesh_reply_err(mesh_reply *r, const char *text);
43void mesh_reply_errf(mesh_reply *r, const char *fmt, ...) __attribute__((format(printf, 2, 3)));
44void mesh_reply_value(mesh_reply *r, uint32_t v);
45void mesh_reply_bytes(mesh_reply *r, const void *p, size_t n);
46/* Ok(ptr): ownership of ptr passes to the receiver (freed with ptr_free if nobody takes it). */
47void mesh_reply_ptr(mesh_reply *r, void *ptr, void (*ptr_free)(void *ptr));
48/* Let go without answering: the waiter sees MESH_CHAN_CLOSED. */
49void mesh_reply_drop(mesh_reply *r);
50
51/* The requester: waits (timeout_ms < 0: forever) and fills out (free it with
52 * mesh_result_free). MESH_CHAN_OK, MESH_CHAN_TIMEOUT or MESH_CHAN_CLOSED. */
53int mesh_reply_wait(mesh_reply *r, int64_t timeout_ms, mesh_result *out);
54/* The requester's poll: MESH_CHAN_OK, MESH_CHAN_EMPTY or MESH_CHAN_CLOSED. */
55int mesh_reply_poll(mesh_reply *r, mesh_result *out);
56/* The requester lets go of its own reference. */
57void mesh_reply_release(mesh_reply *r);
58
59mesh_result mesh_result_ok(const char *text);
60mesh_result mesh_result_err(const char *text);
61/* A copy (text and bytes duplicated; ptr is not copied: NULL in the copy). */
62mesh_result mesh_result_copy(const mesh_result *r);
63void mesh_result_free(mesh_result *r);
64
65#endif