102 using lib::RecursiveLock_Waitable;
103 using std::make_unique;
121 ,
public Sync<RecursiveLock_Waitable>
124 using Launch = lib::ThreadHookable::Launch;
144 template<
typename FUN>
146 : commandService_{ServiceHandle::NOT_YET_STARTED}
149 , looper_([&]() ->
bool 151 return not queue_.empty();
156 .atExit([
this, signalEndOfThread = move(atExit)]
160 signalEndOfThread (&error_);
164 INFO (
session,
"Steam-Dispatcher running...");
167 commandService_.createInstance(*
this);
174 commandService_.shutdown();
175 INFO (
session,
"Steam-Dispatcher stopped.");
177 ALERT (
session,
"Dispatcher destroyed while Session thread is running. The rest is silence.");
183 activateCommandProecssing()
186 looper_.enableProcessing(
true);
187 INFO (command,
"Session command processing activated.");
192 deactivateCommandProecssing()
195 looper_.enableProcessing(
false);
196 INFO (command,
"Session command interface closed.");
201 requestStop() noexcept
204 commandService_.shutdown();
205 looper_.triggerShutdown();
210 awaitStateProcessed()
const 212 Lock{
this, [&]{
return isStateSynched(); }};
220 return queue_.size();
230 queue_.feed (move (
cmd));
259 if (looper_.isDying())
261 if (looper_.runBuild())
264 if (looper_.isWorking())
269 catch (std::exception& problem)
271 error_ = problem.what();
284 Lock{
this}.wait_for (looper_.getTimeout()
292 if (looper_.isDisabled())
293 getMonitor(
this).notify_all();
297 isStateSynched()
const 301 "Attempt to synchronise to a command processing check point " 302 "from within the (single) session thread." 303 , error::LUMIERA_ERROR_LIFECYCLE);
313 if (not queue_.empty())
318 INFO (command,
"+++ dispatch %s",
cStr(cmd));
321 if (util::startsWith (
string(cmd.getID()),
"test"))
323 INFO (command,
"+++ -------->>> bang!");
324 auto resultState = cmd();
325 resultState.maybeThrow();
334 INFO (builder,
"+++ start the Steam-Builder...");
349 SteamDispatcher::SteamDispatcher() { }
350 SteamDispatcher::~SteamDispatcher() { }
364 if (runningLoop_)
return false;
367 make_unique<DispatcherLoop>(
368 [=](
string* problemIndicator)
371 termNotification (problemIndicator);
375 runningLoop_->activateCommandProecssing();
393 runningLoop_.reset();
395 WARN (command,
"clean-up of DispatcherLoop invoked, " 396 "while SteamDispatcher is not marked as 'running'. " 397 "Likely an error in lifecycle logic, as the only one " 398 "intended to delete this object is the loop thread itself.");
410 return bool(runningLoop_);
423 runningLoop_->requestStop();
444 runningLoop_->activateCommandProecssing();
460 runningLoop_->deactivateCommandProecssing();
475 runningLoop_->awaitStateProcessed();
486 WARN (command,
"DISCARDING pending Session commands.");
487 REQUIRE (runningLoop_);
488 runningLoop_->clear();
494 SteamDispatcher::empty()
const 497 return not runningLoop_
498 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.