aboutsummaryrefslogtreecommitdiffstats
path: root/link/sending.h
diff options
context:
space:
mode:
authoreunhhu <[email protected]>2026-10-01 09:00:45 +0100
committereunhhu <[email protected]>2026-10-01 09:00:45 +0100
commit50f8ea3c249009fcbe649561e7aba32580bab454 (patch)
treed7372c9da5f7a1f40b82f83e656e46f3e7970852 /link/sending.h
parent94e7bb87bce6821e91734f1fcbb6cfd61a008049 (diff)
downloadpure-50f8ea3c249009fcbe649561e7aba32580bab454.tar.gz
pure-50f8ea3c249009fcbe649561e7aba32580bab454.zip
Take the sending loop out of the links, for the wires to join it (017, 2b)
link/sending.c is the process's sending loop: a sender joins it with its round and the socket it waits on, and is rounded when its socket is ready, when pushed, and when its time comes. Links are its first senders; nothing they do changed. Events of a sender that left while the loop waited are let go (the epoll is level-triggered: the others' come again).
Diffstat (limited to 'link/sending.h')
-rw-r--r--link/sending.h46
1 files changed, 46 insertions, 0 deletions
diff --git a/link/sending.h b/link/sending.h
new file mode 100644
index 0000000..f6b6227
--- /dev/null
+++ b/link/sending.h
@@ -0,0 +1,46 @@
+#ifndef PURE_SENDING_H
+#define PURE_SENDING_H
+#include <stdatomic.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+/* The process's sending loop (docs/design/017-apps-on-one-host.md, 2b): one
+ * thread, pure-send, sends for every link and wire, an epoll over their
+ * sockets. A sender joins it, and has rounds on that thread: when its socket
+ * is ready, when it was pushed (from any thread: there is more to send), and
+ * when the time it last wanted comes. The thread is made with the first
+ * sender joined and stopped with the last that leaves. A sender is a
+ * PureSending in its struct, with its round. */
+typedef struct PureSending PureSending;
+struct PureSending {
+ /* Its round, with what its socket was ready for (EPOLLIN, EPOLLOUT,
+ * EPOLLERR, EPOLLHUP; 0: pushed, or its time came): when it wants the
+ * next (CLOCK_MONOTONIC ns; 0: when pushed or its socket is ready). */
+ uint64_t (*round)(PureSending *, uint32_t ready);
+ /* The loop's own. */
+ PureSending *next;
+ int fd; /* the socket it waits on, or -1 */
+ uint32_t events; /* for what */
+ bool joined, watched;
+ uint32_t ready;
+ uint64_t due;
+ _Atomic bool pushed;
+};
+
+/* Before it joins: no socket. */
+void pure_sending_init(PureSending *, uint64_t (*round)(PureSending *, uint32_t ready));
+/* Its first round comes at once. False with why in error when the loop
+ * cannot be made. */
+bool pure_sending_join(PureSending *, char *error, size_t size);
+/* Out of the loop: no round of it runs once this returns (one under way is
+ * waited for). Not from a round. */
+void pure_sending_leave(PureSending *);
+/* A round for it soon (any thread); the loop woken when it sleeps. */
+void pure_sending_push(PureSending *);
+/* The socket it waits on and for what (EPOLLIN, EPOLLOUT; fd -1: none), in
+ * its round or before it joins; before the socket it waited on is closed. */
+void pure_sending_watch(PureSending *, int fd, uint32_t events);
+/* Now on CLOCK_MONOTONIC, ns. */
+uint64_t pure_sending_now(void);
+#endif