bio
 
Loading...
Searching...
No Matches
mailbox.h
1#ifndef BIO_MAILBOX_H
2#define BIO_MAILBOX_H
3
4#include <bio/bio.h>
5
64#ifndef DOXYGEN
65
66#if __STDC_VERSION__ >= 202311L
67# define BIO__TYPEOF(EXP) typeof(EXP)
68#elif defined(__clang__) || defined(__GNUC__) || defined(_MSC_VER)
69# define BIO__TYPEOF(EXP) __typeof__(EXP)
70#endif
71
72#ifdef BIO__TYPEOF
73// _Static_assert is actually quite hard to use in an expression.
74// Jamming it into a struct: `sizeof(struct{_Static_assert(...);})` doesn't work
75// quite well.
76// Clang requires the RHS of BIO__TYPECHECK_EXP to be a constant expression
77// which is not always the case in typical user code.
78// The good old negative size array works in all compilers but the error message
79// is somewhat cryptic.
80# define BIO__TYPECHECK_EXP(LHS, RHS) \
81 (void)sizeof(char[_Generic(RHS, BIO__TYPEOF(LHS): 1, default: -1)]) /* If you get an error here, you have the wrong type */
82#else
83// Check both size and assignability as integer types of different sizes are
84// assignable (with warnings).
85// We can't count on user having warnings enabled.
86# define BIO__TYPECHECK_EXP(LHS, RHS) \
87 ((void)sizeof(LHS = RHS), (void)sizeof(char[sizeof(LHS) == sizeof(RHS) ? 1 : -1])) /* If you get an error here, you have the wrong type */
88#endif
89
90#endif
91
97#define BIO_MAILBOX(T) union { bio_handle_t bio__handle; T* bio__message; }
98
108#define bio_open_mailbox(ptr, capacity) \
109 bio__mailbox_open(&(ptr)->bio__handle, sizeof(*(ptr)->bio__message), capacity)
110
120#define bio_close_mailbox(mailbox) \
121 bio__mailbox_close((mailbox).bio__handle)
122
124#define bio_is_mailbox_open(mailbox) \
125 bio__mailbox_is_open((mailbox).bio__handle)
126
147#define bio_send_message(mailbox, message) \
148 ( \
149 BIO__TYPECHECK_EXP(message, *mailbox.bio__message), \
150 bio__mailbox_send(mailbox.bio__handle, &message, sizeof(message)) \
151 )
152
176#define bio_wait_and_send_message(condition, mailbox, message) \
177 do { \
178 while ((bio_is_mailbox_open(mailbox)) && (condition)) { \
179 if (bio_send_message((mailbox), (message))) { break; } \
180 bio_yield(); \
181 } \
182 } while (0)
183
203#define bio_recv_message(mailbox, message) \
204 ( \
205 BIO__TYPECHECK_EXP(*(message), *(mailbox.bio__message)), \
206 bio__mailbox_recv(mailbox.bio__handle, (message), sizeof(*(message))) \
207 )
208
217#define bio_can_recv_message(mailbox) \
218 bio__mailbox_can_recv((mailbox).bio__handle)
219
228#define bio_can_send_message(mailbox) \
229 bio__mailbox_can_send((mailbox).bio__handle)
230
245#define bio_foreach_message(msg, mailbox) \
246 for ( \
247 BIO__TYPEOF(*(mailbox).bio__message) msg; \
248 bio_recv_message(mailbox, &msg); \
249 )
250
251#ifndef DOXYGEN
252
253void
254bio__mailbox_open(bio_handle_t* handle, size_t item_size, uint32_t capacity);
255
256void
257bio__mailbox_close(bio_handle_t handle);
258
259bool
260bio__mailbox_is_open(bio_handle_t handle);
261
262bool
263bio__mailbox_send(bio_handle_t handle, const void* data, size_t message_size);
264
265bool
266bio__mailbox_recv(bio_handle_t handle, void* data, size_t message_size);
267
268bool
269bio__mailbox_can_recv(bio_handle_t handle);
270
271bool
272bio__mailbox_can_send(bio_handle_t handle);
273
274#endif
275
278#endif
Definition bio.h:126