Lumiera
0.pre.03
»edit your freedom«
|
Go to the source code of this file.
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.
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.
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.
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).
Definition in file steam-dispatcher.cpp.
#include "lib/error.hpp"
#include "include/logging.h"
#include "steam/control/steam-dispatcher.hpp"
#include "steam/control/command-dispatch.hpp"
#include "steam/control/command-queue.hpp"
#include "steam/control/looper.hpp"
#include "steam/control/session-command-service.hpp"
#include "steam/mobject/session.hpp"
#include "lib/depend-inject.hpp"
#include "lib/sync-barrier.hpp"
#include "lib/thread.hpp"
#include "lib/util.hpp"
#include <utility>
#include <memory>
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. | |