Event-driven Programming

In event-driven programming, the flow of a program is determined by events triggered through a defined interaction (e.g., user interaction, exceeding threshold limit, etc. ). Usually, a main loop listens for events, and then triggers a callback function when an event is detected.

Overall, Legato components are written using an event-driven model. Callback functions are attached to specific events, and when events occur, the thread's event loop triggers the appropriate callbacks. Legato components can also start other threads that run their own Legato event loops.

Every component implements an initialization function called at process start-up by the main thread. That function does whatever initialization is required for that component (e.g., initializes data structures, registers callbacks, starts threads, etc.) and returns. After all initialization functions have run to completion and returned, the main thread enters the Legato event loop and begins reacting to events and calling registered callbacks.

This allows multiple components to be deployed to the same process and even share a single thread within that process, without having to know anything about each other. This reduces the risk of multi-threaded race conditions and saves stack memory space.

Beware one drawback is that if a component blocks a shared thread, it blocks every component sharing that thread.

Sometimes, the judicious use of threads can considerably simplify a program, so multi-threading is also supported by Legato along with the usual thread synchronization constructs (mutexes, semaphores, etc.).

Event Loop API

Legato's Event Loop API uses a central event loop that calls event handler functions in response to event reports. See Event Loop API

Software components register their event handler functions with the event system (either directly through the Event Loop API or indirectly through other APIs that use the Event Loop API) so the central event loop knows the functions to call in response to defined events.

Every event loop has an event queue, which is a queue of events waiting to be handled by that event loop.

The following different usage patterns are supported by the Event Loop API:

Deferred Function Calls
Publish-Subscribe Events
Layered Publish-Subscribe Handlers
Dispatching Function Execution to Other Threads