Lumiera  0.pre.03
»edit your freedom«
steam-dispatcher.cpp File Reference

Go to the source code of this file.

Description

Implementation details of running commands and the builder.

The SteamDispatcher is at the heart of the session subsystem and implements a (single) session thread to perform commands and trigger builder runs. New commands can be enqueued with a dedicated CommandQueue, while the details of operation control logic are encapsulated in a processing logic component.

Operational Semantics

We need to distinguish between the SteamDispatcher itself, which is a static (singleton) service, and the »Session Subsystem« plus the Session proper. The subsystem has an application-global lifecycle, while the Session itself is a data structure and can be closed, opened or re-loaded. There is a singular transactional access point to the Session datastructure, which can be switched to new session contents. But external manipulation of the session contents is performed by commands, which are dispatched – and the management of this process is the concern served by the »Session Subsystem«.

Closing a session blocks further command processing, while the lifecycle of the Session Subsystem is actually linked to _running the DispatcherLoop_ – a piece of implementation logic defined within this translation unit. The loop implementation is performed within a dedicated thread, the Session Loop Thread. And this also entails opening the public SessionCommandService interface.

Loop operation control

The loop starts with a blocking wait state, bound to the condition Looper::requireAction. The Looper is a helper to encapsulate the control logic, separated from the actual control flow. In the loop body, depending on the Looper's decision, either the next command is fetched from the CommandQueue and dispatched, or a builder run is triggered, rebuilding the »Low-Level-Model« to reflect the executed command's effects. After these working actions, a _"check point"_ is reached in Looper::markStateProcessed, which updates the logic and manages a dirty state to control builder runs. After that, the looping control flow again enters the possibly blocking condition wait.

  • after a command has been dispatched, the builder is dirty and needs to run
  • yet we continue to dispatch further commands, until the queue is emptied
  • and only after a further small latency wait, the builder run is triggered
  • but we enforce a builder run after some extended timeout period, even when the command queue is not emptied yet
  • from the outside, it is possible to deactivate processing and place the loop into dormant state. This is used while closing or loading the Session
  • and of course we can request the Session Loop Thread to stop, for shutting down the »Session Subsystem« as a whole
  • in both cases the currently performed action (command or builder) is finished, without interruption.

Locking

The SteamDispatcher uses an "inner and outer capsule" design, and both layers are locked independently. On the outer layer, locking ensures sanity of the control data structures, while locking on the inner layer guards the communication with the Session Loop Thread, and coordinates sleep wait and notification. As usual with Lumiera's Thread wrapper, the management of the thread's lifecycle itself, hand-over of parameters, and starting / joining of the thread operation is protected by means of synchronisation embedded into the underlying implementation (C++ standard library thread support).

Note
most of the time, the Session Loop Thread does not hold any lock, most notably while performing a command or running the builder. Likewise, evaluation of the control logic in the Looper helper is a private detail of the performing thread. The lock is acquired solely for checking or leaving the wait state and when fetching the next command from queue.
See also
SteamDispatcher
DispatcherLooper_test
CommandQueue_test

Definition in file steam-dispatcher.cpp.

Classes

class  DispatcherLoop
 PImpl within SteamDispatcher to implement the Session Loop Thread. During the lifetime of this object... More...
 

Namespaces

 steam
 Steam-Layer implementation namespace root.
 
 steam::control
 Steam-Layer dispatcher, controller and administrative facilities.