93 using lib::RecursiveLock_Waitable;
94 using std::make_unique;
112 ,
public Sync<RecursiveLock_Waitable>
115 using Launch = lib::ThreadHookable::Launch;
135 template<
typename FUN>
137 : commandService_{ServiceHandle::NOT_YET_STARTED}
140 , looper_([&]() ->
bool 142 return not queue_.empty();
147 .atExit([
this, signalEndOfThread = move(atExit)]
151 signalEndOfThread (&error_);
155 INFO (
session,
"Steam-Dispatcher running...");
158 commandService_.createInstance(*
this);
165 commandService_.shutdown();
166 INFO (
session,
"Steam-Dispatcher stopped.");
168 ALERT (
session,
"Dispatcher destroyed while Session thread is running. The rest is silence.");
174 activateCommandProecssing()
177 looper_.enableProcessing(
true);
178 INFO (command,
"Session command processing activated.");
183 deactivateCommandProecssing()
186 looper_.enableProcessing(
false);
187 INFO (command,
"Session command interface closed.");
192 requestStop() noexcept
195 commandService_.shutdown();
196 looper_.triggerShutdown();
201 awaitStateProcessed()
const 203 Lock{
this, [&]{
return isStateSynched(); }};
211 return queue_.size();
221 queue_.feed (move (
cmd));
250 if (looper_.isDying())
252 if (looper_.runBuild())
255 if (looper_.isWorking())
260 catch (std::exception& problem)
262 error_ = problem.what();
275 Lock{
this}.wait_for (looper_.getTimeout()
283 if (looper_.isDisabled())
284 getMonitor(
this).notify_all();
288 isStateSynched()
const 292 "Attempt to synchronise to a command processing check point " 293 "from within the (single) session thread." 294 , error::LUMIERA_ERROR_LIFECYCLE);
304 if (not queue_.empty())
309 INFO (command,
"+++ dispatch %s",
cStr(cmd));
312 if (util::startsWith (
string(cmd.getID()),
"test"))
314 INFO (command,
"+++ -------->>> bang!");
315 auto resultState = cmd();
316 resultState.maybeThrow();
325 INFO (builder,
"+++ start the Steam-Builder...");
340 SteamDispatcher::SteamDispatcher() { }
341 SteamDispatcher::~SteamDispatcher() { }
355 if (runningLoop_)
return false;
358 make_unique<DispatcherLoop>(
359 [=](
string* problemIndicator)
362 termNotification (problemIndicator);
366 runningLoop_->activateCommandProecssing();
384 runningLoop_.reset();
386 WARN (command,
"clean-up of DispatcherLoop invoked, " 387 "while SteamDispatcher is not marked as 'running'. " 388 "Likely an error in lifecycle logic, as the only one " 389 "intended to delete this object is the loop thread itself.");
401 return bool(runningLoop_);
414 runningLoop_->requestStop();
435 runningLoop_->activateCommandProecssing();
451 runningLoop_->deactivateCommandProecssing();
466 runningLoop_->awaitStateProcessed();
477 WARN (command,
"DISCARDING pending Session commands.");
478 REQUIRE (runningLoop_);
479 runningLoop_->clear();
485 SteamDispatcher::empty()
const 488 return not runningLoop_
489 or 0 == runningLoop_->size();
Facility for monitor object based locking.
DispatcherLoop(FUN &&atExit)
start the session loop thread
static lib::Depend< SteamDispatcher > instance
storage for Singleton access
void awaitDeactivation()
block until the dispatcher has actually reached disabled state.
void runSessionThread()
any operation running in the Session thread is started from here.
bool invokedWithinThread() const
detect if the currently executing code runs within this thread
CStr cStr(std::string const &rendered)
convenience shortcut: forced conversion to c-String via string.
#define ERROR_LOG_AND_IGNORE(_FLAG_, _OP_DESCR_)
convenience shortcut for a sequence of catch blocks just logging and consuming an error...
Configuration handle to expose a service implementation through the Depend<SRV> front-end.
bool hasPendingChanges() const
< "check point"
Interface to abstract the SteamDispatcher's ability to handle command messages.
Per type specific configuration of instances created as service dependencies.
Dispatch and execute mutation operations on the High-level model.
void clear()
discard any commands waiting in the dispatcher queue
A public service offered by the Session, implementing the SessionCommand facade interface.
This header is for including and configuring NoBug.
Steam-Layer implementation namespace root.
Implementation building block of SteamDispatcher to organise commands.
Namespace of Session and user visible high-level objects.
Access point to singletons and other kinds of dependencies designated by type.
ServiceHandle commandService_
manage the primary public Session interface
bool shallLoop() const
state fusion to control looping
bool requireAction()
state fusion to control (timed) wait
Implementation building block of SteamDispatcher to control waiting and timing.
bool start(Subsys::SigTerm)
starting the SteamDispatcher means to start the session subsystem.
Derived specific exceptions within Lumiera's exception hierarchy.
Interface of a service to perform Commands on the session.
void endRunningLoopState()
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
void markStateProcessed()
invoking this function signals that all consequences of past state changes have been processed and ar...
lumiera_err lumiera_error(void)
Get and clear current error state.
void requestStop() noexcept
signal to the loop thread that it needs to terminate.
Convenience front-end to simplify and codify basic thread handling.
Lumiera error handling (C++ interface).
Implementation of the Session's command queue.
void deactivate()
halt further processing of session commands
A one time N-fold mutual synchronisation barrier.
Handle object representing a single Command instance to be used by client code.
Extended variant of the standard case, allowing to install callbacks (hook functions) to be invoked d...
PImpl within SteamDispatcher to implement the Session Loop Thread. During the lifetime of this object...
Primary Interface to the current Session.
Encapsulated control logic for the session thread loop.
void activate()
activate processing of enqueued session commands.
bool isRunning()
whether the »session subsystem« is operational.
void detach_thread_from_wrapper()
allow to detach explicitly — independent from thread-function's state.
A N-fold synchronisation latch using yield-wait until fulfilment.