AxlLoop -- Event Loop ===================== Event loop with timer, keyboard, idle, protocol notification, and raw event sources. GLib-inspired main loop with FUSE-style primitives. Also includes the deferred work queue (``AxlDefer``) and the publish/subscribe event bus (``AxlSignal``), both integrated with the loop. Headers: - ```` -- Event loop core - ```` -- Deferred work queue (ring buffer) - ```` -- Publish/subscribe event bus Overview -------- UEFI applications are single-threaded and event-driven. The event loop is the central dispatcher: it waits for events (timers, keyboard input, network I/O, custom events) and calls registered callbacks. Basic Pattern ~~~~~~~~~~~~~ .. code-block:: c #include static bool on_timer(void *data) { axl_printf("tick\n"); return AXL_SOURCE_CONTINUE; // keep firing } static bool on_timeout(void *data) { axl_loop_quit(data); return AXL_SOURCE_REMOVE; // one-shot, auto-removed } int main(int argc, char **argv) { AXL_AUTOPTR(AxlLoop) loop = axl_loop_new(); axl_loop_add_timer(loop, 1000, on_timer, NULL); // every 1s axl_loop_add_timeout(loop, 5000, on_timeout, loop); // quit after 5s axl_loop_run(loop); // blocks until axl_loop_quit return 0; } Source Types ~~~~~~~~~~~~ ================= ======================================= ======================== Source Purpose Callback returns ================= ======================================= ======================== Timer Repeating at fixed interval CONTINUE or REMOVE Timeout One-shot after delay Always REMOVE (auto) Idle Runs when no other events pending CONTINUE or REMOVE Keypress Console keyboard input CONTINUE or REMOVE Raw Event Any ``EFI_EVENT`` CONTINUE or REMOVE Protocol Notify Fires when a protocol is installed CONTINUE or REMOVE ================= ======================================= ======================== Run vs. Next+Dispatch ~~~~~~~~~~~~~~~~~~~~~ ``axl_loop_run`` blocks until ``axl_loop_quit`` is called. For manual control (e.g., FUSE-style drivers), use the step API: .. code-block:: c while (running) { axl_loop_next_event(loop, 100); // wait up to 100ms axl_loop_dispatch_event(loop); // fire callbacks // ... do other work between iterations ... } AxlDefer -------- Deferred work queue -- schedules a function to run on the next loop iteration. Useful in constrained contexts (protocol notifications, nested callbacks) where complex work isn't safe. .. code-block:: c // Called from a protocol notification (can't do complex work here) void on_protocol_installed(void *ctx) { axl_defer(initialize_new_protocol, ctx); } // Runs safely on the next main loop tick void initialize_new_protocol(void *ctx) { // Boot Services calls are safe here locate_and_configure(ctx); } The queue is a fixed-capacity ring buffer with no dynamic allocation in the hot path. ``axl_defer_cancel`` can remove pending work before it fires. AxlSignal --------- Publish/subscribe event bus for decoupling modules. Modules emit named signals; other modules subscribe with callbacks. Delivery is deferred (via AxlDefer) so handlers run in a safe context. .. code-block:: c // Producer (network module) axl_signal_emit("ip-changed", &new_ip); // Consumer 1 (splash screen) axl_signal_connect("ip-changed", update_splash_ip, NULL); // Consumer 2 (REST API) axl_signal_connect("ip-changed", update_api_endpoint, NULL); // Adding a third consumer requires zero changes to the producer. Signals are auto-created on first ``connect`` or ``emit``. ``axl_signal_disconnect`` removes a specific subscription. API Reference ------------- AxlLoop ~~~~~~~ .. doxygenfile:: axl-loop.h AxlDefer ~~~~~~~~ .. doxygenfile:: axl-defer.h AxlSignal ~~~~~~~~~ .. doxygenfile:: axl-signal.h