summaryrefslogtreecommitdiff
path: root/sysdep/unix
diff options
context:
space:
mode:
authorMaria Matejka <mq@ucw.cz>2022-09-12 10:24:55 +0200
committerMaria Matejka <mq@ucw.cz>2022-09-18 16:33:51 +0200
commiteac634575959a3d32007ebed9921897976c9a82d (patch)
treea263dd20f62c90b456fb4836705903f516e406fa /sysdep/unix
parent66f27005ec1a3e1fa78733aad56dcd976fbb2744 (diff)
Loop flags: a simple idempotent event announcement mechanism
Diffstat (limited to 'sysdep/unix')
-rw-r--r--sysdep/unix/io-loop.c27
-rw-r--r--sysdep/unix/io-loop.h3
2 files changed, 29 insertions, 1 deletions
diff --git a/sysdep/unix/io-loop.c b/sysdep/unix/io-loop.c
index b7c858c6..575e5403 100644
--- a/sysdep/unix/io-loop.c
+++ b/sysdep/unix/io-loop.c
@@ -59,6 +59,31 @@ birdloop_inside(struct birdloop *loop)
return 0;
}
+void
+birdloop_flag(struct birdloop *loop, u32 flag)
+{
+ atomic_fetch_or_explicit(&loop->flags, flag, memory_order_acq_rel);
+ birdloop_ping(loop);
+}
+
+void
+birdloop_flag_set_handler(struct birdloop *loop, struct birdloop_flag_handler *fh)
+{
+ ASSERT_DIE(birdloop_inside(loop));
+ loop->flag_handler = fh;
+}
+
+static int
+birdloop_process_flags(struct birdloop *loop)
+{
+ if (!loop->flag_handler)
+ return 0;
+
+ u32 flags = atomic_exchange_explicit(&loop->flags, 0, memory_order_acq_rel);
+ loop->flag_handler->hook(loop->flag_handler, flags);
+ return !!flags;
+}
+
/*
* Wakeup code for birdloop
*/
@@ -516,7 +541,7 @@ birdloop_main(void *arg)
while (1)
{
timers_fire(&loop->time, 0);
- if (ev_run_list(&loop->event_list))
+ if (birdloop_process_flags(loop) + ev_run_list(&loop->event_list))
timeout = 0;
else if (t = timers_first(&loop->time))
timeout = (tm_remains(t) TO_MS) + 1;
diff --git a/sysdep/unix/io-loop.h b/sysdep/unix/io-loop.h
index 31c40459..aec7a409 100644
--- a/sysdep/unix/io-loop.h
+++ b/sysdep/unix/io-loop.h
@@ -34,6 +34,9 @@ struct birdloop
uint links;
+ _Atomic u32 flags;
+ struct birdloop_flag_handler *flag_handler;
+
void (*stopped)(void *data);
void *stop_data;