==> tests/reply.c <==1/* Answered, dropped unanswered, answered too late, and across threads. */
2#include "mesh/check.h"
3#include "mesh/buf.h"
4#include "mesh/reply.h"
5
6#include <stdlib.h>
7
8#include <pthread.h>
9
10static void *answer_later(void *arg) {
11 mesh_sleep_us(20000);
12 mesh_reply_okf(arg, "%s %d", "blink", 412);
13 return NULL;
14}
15
16int main(void) {
17 mesh_reply *r = mesh_reply_new();
18 mesh_reply_ok(mesh_reply_sender(r), "slot 3");
19 mesh_result x;
20 CHECK_I(mesh_reply_wait(r, 100, &x), MESH_CHAN_OK);
21 CHECK(x.ok);
22 CHECK_S(x.text, "slot 3");
23 mesh_result_free(&x);
24 mesh_reply_release(r);
25
26 /* Dropped unanswered: the waiter knows at once. */
27 r = mesh_reply_new();
28 mesh_reply_drop(mesh_reply_sender(r));
29 int64_t t0 = mesh_mono_ms();
30 CHECK_I(mesh_reply_wait(r, 5000, &x), MESH_CHAN_CLOSED);
31 CHECK(mesh_mono_ms() - t0 < 1000);
32 mesh_reply_release(r);
33
34 /* A thread answers within the timeout. */
35 r = mesh_reply_new();
36 pthread_t th;
37 pthread_create(&th, NULL, answer_later, mesh_reply_sender(r));
38 CHECK_I(mesh_reply_wait(r, 5000, &x), MESH_CHAN_OK);
39 CHECK_S(x.text, "blink 412");
40 mesh_result_free(&x);
41 pthread_join(th, NULL);
42 mesh_reply_release(r);
43
44 /* Too late: the waiter gave up; the answer is freed with the channel (no leak under ASan). */
45 r = mesh_reply_new();
46 mesh_reply *s = mesh_reply_sender(r);
47 CHECK_I(mesh_reply_wait(r, 10, &x), MESH_CHAN_TIMEOUT);
48 mesh_reply_release(r);
49 mesh_reply_errf(s, "no program %s", "\"x\"");
50
51 /* Values and bytes; clones. */
52 r = mesh_reply_new();
53 mesh_reply *c = mesh_reply_clone(r);
54 mesh_reply_value(mesh_reply_sender(r), 7);
55 mesh_reply_bytes(c, "abc", 3);
56 CHECK_I(mesh_reply_wait(r, 100, &x), MESH_CHAN_OK);
57 CHECK_U(x.value, 7);
58 CHECK_I(mesh_reply_wait(r, 100, &x), MESH_CHAN_OK);
59 CHECK_U(x.len, 3);
60 CHECK(x.bytes[0] == 'a' && x.bytes[2] == 'c');
61 mesh_result_free(&x);
62 mesh_reply_release(r);
63
64 /* A pointer payload: taken, or freed with the channel when nobody waits. */
65 r = mesh_reply_new();
66 mesh_reply_ptr(mesh_reply_sender(r), mesh_xstrdup("inventory"), free);
67 CHECK_I(mesh_reply_wait(r, 100, &x), MESH_CHAN_OK);
68 CHECK_S(x.ptr, "inventory");
69 mesh_result_free(&x);
70 mesh_reply_release(r);
71 r = mesh_reply_new();
72 s = mesh_reply_sender(r);
73 mesh_reply_release(r);
74 mesh_reply_ptr(s, mesh_xstrdup("nobody"), free);
75 return mesh_check_done();
76}