commit b6d66746d2680e1cc60a4eef54ba86ed559b8f37
parent eab5b7383124afd2f84ee52cb53b4324730a3266
Author: Henry Wilson <henry@henryandlizzy.uk>
Date: Sat, 6 Aug 2022 00:21:49 +0100
epoll: Add timerfd example
Diffstat:
A | src/timerfd.c | | | 82 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1 file changed, 82 insertions(+), 0 deletions(-)
diff --git a/src/timerfd.c b/src/timerfd.c
@@ -0,0 +1,82 @@
+#include <sys/epoll.h>
+#include <sys/timerfd.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+static int timer, event_queue;
+
+static void succeed_or_die(int n, char const* msg)
+{
+ if (n >= 0)
+ return;
+
+ perror(msg);
+ exit(1);
+}
+
+static void stdin_event(void)
+{
+ char buf[64];
+ int n = read(STDIN_FILENO, buf, sizeof buf - 1);
+
+ if (n <= 0)
+ {
+ puts("Stdin closed.");
+ exit(0);
+ }
+ for (int i = 0; i < n; ++i)
+ if (iscntrl(buf[i]))
+ buf[i] = '.';
+ buf[n] = '\0';
+
+ printf("Stdin: '%s'\n", buf);
+}
+
+static void timerfd_event(void)
+{
+ static uint64_t ticks;
+ uint64_t new_ticks;
+ read(timer, &new_ticks, sizeof new_ticks);
+ ticks += new_ticks;
+ printf("Tick +%lu %lu\n", new_ticks, ticks);
+}
+
+int main()
+{
+ timer = timerfd_create(CLOCK_MONOTONIC, 0);
+ succeed_or_die(timer, "timerfd_create");
+
+ int res = timerfd_settime(timer, 0, &(struct itimerspec){
+ .it_interval = {1, 0}, /* Interval for periodic timer */
+ .it_value = {1, 0}, /* Initial expiration */
+ }, NULL);
+ succeed_or_die(res, "timerfd_settime");
+
+ event_queue = epoll_create1(0);
+ succeed_or_die(event_queue, "epoll_create2");
+
+ res = epoll_ctl(event_queue, EPOLL_CTL_ADD, STDIN_FILENO, &(struct epoll_event){
+ .events = EPOLLIN,
+ .data.ptr = stdin_event,
+ });
+ succeed_or_die(res, "epoll_ctl");
+
+ res = epoll_ctl(event_queue, EPOLL_CTL_ADD, timer, &(struct epoll_event){
+ .events = EPOLLIN,
+ .data.ptr = timerfd_event,
+ });
+ succeed_or_die(res, "epoll_ctl");
+
+ for (;;)
+ {
+ struct epoll_event events[8];
+ int n_events = epoll_wait(event_queue, events, sizeof events / sizeof *events, -1);
+ succeed_or_die(n_events, "epoll_wait");
+
+ for (int i = 0; i < n_events; ++i)
+ ((void(*)(void))events[i].data.ptr)();
+ }
+}