RIOT icon indicating copy to clipboard operation
RIOT copied to clipboard

sys/event: No way to stop event queue?!

Open carl-tud opened this issue 2 months ago • 1 comments

Is there a way to stop an event queue? event_loop(_:) seemingly runs forever. There should be one. If no, why?

carl-tud avatar Oct 08 '25 14:10 carl-tud

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;
}

mguetschow avatar Oct 30 '25 08:10 mguetschow

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.

carl-tud avatar Dec 20 '25 11:12 carl-tud

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).

maribu avatar Dec 23 '25 09:12 maribu

IMO, the increased complexity you mentioned is just a consequence of not considering this in the first place.

carl-tud avatar Dec 23 '25 09:12 carl-tud

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.

maribu avatar Dec 23 '25 09:12 maribu