sys/event: No way to stop event queue?!
Is there a way to stop an event queue? event_loop(_:) seemingly runs forever. There should be one. If no, why?
I've briefly looked into this and I think it turns out to be a bit cumbersome in a general implementation, given that event_loop is implemented under the hood with event_loop_multi, where it wouldn't be as clear what "stopping the event queue" means - just stop listening on one (you'd need more state) or stop listening on all of them?
https://github.com/RIOT-OS/RIOT/blob/9890215cf182949322f15a7a34bbb4d2c54c8b20/sys/include/event.h#L436-L439
But given that event_loop is just a static inline which
https://github.com/RIOT-OS/RIOT/blob/9890215cf182949322f15a7a34bbb4d2c54c8b20/sys/include/event.h#L470-L476
you can solve that for your particular use-case along the lines of
static bool _running = false;
static void _start_loop(event_queue_t *queue)
{
running = true;
while (_running) {
event_t *event = event_wait(queue);
event->handler(event);
}
}
static void __stop_loop(event_t *ev)
{
_running = false;
}
static void _stop_loop(event_queue_t *queue)
{
static event_t ev = { .handler = __stop_loop };
event_post(queue, &ev);
event_sync(queue); // if you want to wait until the loop is stopped (from another thread)
// or just (if only called from within the loop / the same thread)
// _running = false;
}
By stopping I mean not waiting for further events, i.e., just breaking out of the loop that waits for new events. Thanks for the proof of concept, I just thought this would be a common use case and that there should be some API for that that doesn't require me to rebuild part of the public API.
IMO we should avoid making the default API for the event loop more complex. Adding a separate API for a "stoppable" event loop would IMO be the way to go.
What is btw. the use case? Have you seen the event_threads module that just spawns one or more system-wide event handler threads? IMO it is totally acceptable to use them even if you only temporarily need someone running an event queue. The moment another module that needs an event handler gets also used, you start saving RAM (assuming the other module also uses event_threads).
IMO, the increased complexity you mentioned is just a consequence of not considering this in the first place.
Given that we have sys/event since 2017 and the first time a use case for breaking the event queue popped up is 2025, I think it was a good design decision to limit the API to the "running forever" event thread.
The ability to break the event loop costs RAM to track state and code to check and branch depending on the state. If that had been included from the start, all uses of sys/event would have paid that overhead for 8 years without anyone actually using it.
I think it is only fair if that overhead is only paid by code actually needing the ability to break an event loop. Thus, a separate API.