Provides an Event loop.
More...
Provides an Event loop.
This module offers an event queue framework like libevent or libuev.
An event queue is basically a FIFO queue of events, with some functions to efficiently and safely handle adding and getting events to / from such a queue.
An event queue is bound to a thread, but any thread or ISR can put events into a queue. In most cases, the owning thread of a queue is set during the queue's initialization. But it is also possible to initialize a queue in a detached state from a different context and to set the owning thread at a later point of time using the event_queue_claim() function.
An event is a structure containing a pointer to an event handler. It can be extended to provide context or arguments to the handler. It can also be embedded into existing structures (see examples).
Compared to msg or mbox, this some fundamental differences:
- events are "sender allocated". Unlike msg_send(), event_post() never blocks or fails.
- events contain everything necessary to handle them, thus a thread processing the events of an event queue doesn't need to be changed in order to support new event types.
- events can be safely used (and actually perform best) when used within one thread, e.g., in order to create a state-machine like process flow. This is not (easily) possible using msg queues, as they might fill up.
- an event can only be queued in one event queue at the same time. Notifying many queues using only one event object is not possible with this implementation.
At the core, event_wait() uses thread flags to implement waiting for events to be queued. Thus event queues can be used safely and efficiently in combination with thread flags and msg queues.
Examples:
{
printf(
"triggered 0x%08x\n", (
unsigned)
event);
}
int main(void)
{
}
typedef struct {
const char *text;
} custom_event_t;
{
custom_event_t *custom_event = (custom_event_t *)
event;
printf("triggered custom event with text: \"%s\"\n", custom_event->text);
}
static custom_event_t custom_event = { .super.handler = custom_handler, .text = "CUSTOM EVENT" };
|
file | callback.h |
| Provides a callback-with-argument event type.
|
|
file | thread.h |
| Provides utility functions for event handler threads.
|
|
file | timeout.h |
| Provides functionality to trigger events after timeout.
|
|
file | event.h |
| Event API.
|
|
|
static void | event_queues_init (event_queue_t *queues, size_t n_queues) |
| Initialize an array of event queues. More...
|
|
static void | event_queue_init (event_queue_t *queue) |
| Initialize an event queue. More...
|
|
static void | event_queues_init_detached (event_queue_t *queues, size_t n_queues) |
| Initialize an array of event queues not binding it to a thread. More...
|
|
static void | event_queue_init_detached (event_queue_t *queue) |
| Initialize an event queue not binding it to a thread. More...
|
|
static void | event_queues_claim (event_queue_t *queues, size_t n_queues) |
| Bind an array of event queues to the calling thread. More...
|
|
static void | event_queue_claim (event_queue_t *queue) |
| Bind an event queue to the calling thread. More...
|
|
void | event_post (event_queue_t *queue, event_t *event) |
| Queue an event. More...
|
|
void | event_cancel (event_queue_t *queue, event_t *event) |
| Cancel a queued event. More...
|
|
event_t * | event_get (event_queue_t *queue) |
| Get next event from event queue, non-blocking. More...
|
|
event_t * | event_wait_multi (event_queue_t *queues, size_t n_queues) |
| Get next event from the given event queues, blocking. More...
|
|
static event_t * | event_wait (event_queue_t *queue) |
| Get next event from event queue, blocking. More...
|
|
event_t * | event_wait_timeout (event_queue_t *queue, uint32_t timeout) |
| Get next event from event queue, blocking until timeout expires. More...
|
|
event_t * | event_wait_timeout64 (event_queue_t *queue, uint64_t timeout) |
| Get next event from event queue, blocking until timeout expires. More...
|
|
static void | event_loop_multi (event_queue_t *queues, size_t n_queues) |
| Simple event loop with multiple queues. More...
|
|
static void | event_loop (event_queue_t *queue) |
| Simple event loop. More...
|
|
◆ event_cancel()
Cancel a queued event.
This will remove a queued event from an event queue.
- Note
- Due to the underlying list implementation, this will run in O(n).
- Parameters
-
[in] | queue | event queue to remove event from |
[in] | event | event to remove from queue |
◆ event_get()
Get next event from event queue, non-blocking.
In order to handle an event retrieved using this function, call event->handler(event).
- Parameters
-
[in] | queue | event queue to get event from |
- Returns
- pointer to next event
-
NULL if no event available
◆ event_loop()
Simple event loop.
This function will forever sit in a loop, waiting for events to be queued and executing their handlers.
It is pretty much defined as:
- Parameters
-
[in] | queue | event queue to process |
Definition at line 404 of file event.h.
◆ event_loop_multi()
static void event_loop_multi |
( |
event_queue_t * |
queues, |
|
|
size_t |
n_queues |
|
) |
| |
|
inlinestatic |
Simple event loop with multiple queues.
This function will forever sit in a loop, waiting for events to be queued and executing their handlers. If more than one queue contains an event, the queue with the lowest index is chosen. Thus, a lower index in the queues
array translates into a higher priority of the queue.
It is pretty much defined as:
- See also
- event_wait_multi
- Parameters
-
[in] | queues | Event queues to process |
[in] | n_queues | Number of queues passed with queues |
Definition at line 379 of file event.h.
◆ event_post()
Queue an event.
The given event will be posted on the given queue
. If the event is already queued when calling this function, the event will not be touched and remain in the previous position on the queue. So reposting an event while it is already on the queue will have no effect.
- Parameters
-
[in] | queue | event queue to queue event in |
[in] | event | event to queue in event queue |
◆ event_queue_claim()
Bind an event queue to the calling thread.
This function must only be called once and only if the given queue is not yet bound to a thread.
- Precondition
- (queue->waiter == NULL)
- Parameters
-
[out] | queue | event queue object to bind to a thread |
Definition at line 243 of file event.h.
◆ event_queue_init()
Initialize an event queue.
This will set the calling thread as owner of queue
.
- Parameters
-
[out] | queue | event queue object to initialize |
Definition at line 182 of file event.h.
◆ event_queue_init_detached()
Initialize an event queue not binding it to a thread.
- Parameters
-
[out] | queue | event queue object to initialize |
Definition at line 207 of file event.h.
◆ event_queues_claim()
static void event_queues_claim |
( |
event_queue_t * |
queues, |
|
|
size_t |
n_queues |
|
) |
| |
|
inlinestatic |
Bind an array of event queues to the calling thread.
This function must only be called once and only if the given queue is not yet bound to a thread.
- Precondition
- (queues[i].waiter == NULL for i in {0, ..., n_queues - 1})
- Parameters
-
[out] | queues | event queue objects to bind to a thread |
[in] | n_queues | number of queues in queues |
Definition at line 223 of file event.h.
◆ event_queues_init()
static void event_queues_init |
( |
event_queue_t * |
queues, |
|
|
size_t |
n_queues |
|
) |
| |
|
inlinestatic |
Initialize an array of event queues.
This will set the calling thread as owner of each queue in queues
.
- Parameters
-
[out] | queues | event queue objects to initialize |
[in] | n_queues | number of queues in queues |
Definition at line 164 of file event.h.
◆ event_queues_init_detached()
static void event_queues_init_detached |
( |
event_queue_t * |
queues, |
|
|
size_t |
n_queues |
|
) |
| |
|
inlinestatic |
Initialize an array of event queues not binding it to a thread.
- Parameters
-
[out] | queues | event queue objects to initialize |
[in] | n_queues | number of queues in queues |
Definition at line 193 of file event.h.
◆ event_wait()
Get next event from event queue, blocking.
This function will block until an event becomes available.
In order to handle an event retrieved using this function, call event->handler(event).
- Warning
- There can only be a single waiter on a queue!
- Parameters
-
[in] | queue | event queue to get event from |
- Returns
- pointer to next event
Definition at line 329 of file event.h.
◆ event_wait_multi()
Get next event from the given event queues, blocking.
This function will block until an event becomes available. If more than one queue contains an event, the queue with the lowest index is chosen. Thus, a lower index in the queues
array translates into a higher priority of the queue.
In order to handle an event retrieved using this function, call event->handler(event).
- Warning
- There can only be a single waiter on a queue!
- Note
- This function can be suitable for having a single thread handling both real-time and non-real-time events. However, a real time event can be delayed for the whole duration a single non-real-time event takes (in addition to all other sources of latency). Thus, the slowest to handle non-real-time event must still execute fast enough to add an amount of latency (on top of other sources of latency) that is acceptable to the real-time event with the strictest requirements.
- Parameters
-
[in] | queues | Array of event queues to get event from |
[in] | n_queues | Number of event queues passed in queues |
- Returns
- pointer to next event
◆ event_wait_timeout()
Get next event from event queue, blocking until timeout expires.
- Parameters
-
[in] | queue | queue to query for an event |
[in] | timeout | maximum time to wait for an event to be posted in us |
- Returns
- pointer to next event if event was taken from the queue
-
NULL if timeout expired before an event was posted
◆ event_wait_timeout64()
Get next event from event queue, blocking until timeout expires.
- Parameters
-
[in] | queue | queue to query for an event |
[in] | timeout | maximum time to wait for an event to be posted in us |
- Returns
- pointer to next event if event was taken from the queue
-
NULL if timeout expired before an event was posted