10 InstancePtr->BlockUntilReadyToStart();
14 bool IsExiting =
false;
15 bool IsFirstRun =
true;
17 std::chrono::time_point<std::chrono::system_clock> LastUpdate;
21 auto& NewTaskNotifier = Instrument->GetInstrumentData()->InstrumentThreadOnly.GetNewTaskNotifier();
25 if (Instrument->IsExiting())
29 while (Instrument->GetInstrumentData()->GetNumEnqueuedTasks())
31 DoContinue = Instrument->InstrumentThreadOnly.HandleTask(Instance);
43 auto TaskQueueDelay = Instrument->GetTaskQueueDelay();
44 auto Now = std::chrono::system_clock::now();
47 (Now - LastUpdate >= TaskQueueDelay || TaskQueueDelay ==
decltype(TaskQueueDelay)::max()))
49 Instrument->InstrumentThreadOnly.UpdateData();
52 Instrument->GetInstrumentData()->InstrumentThreadOnly.SetLastUpdateTime(Now);
57 if (TaskQueueDelay ==
decltype(TaskQueueDelay)::max())
58 NewTaskNotifier.Wait();
59 else if (TaskQueueDelay.count() == 0)
60 std::this_thread::yield();
62 NewTaskNotifier.Wait(TaskQueueDelay);
69 Instrument->InstrumentThreadOnly.SetInitialized();
79 Instrument->InstrumentThreadOnly.SetException(std::current_exception());
80 Instrument->InstrumentThreadOnly.OnError();
84 catch (
const std::exception& e)
88 Instrument->InstrumentThreadOnly.SetException(std::current_exception());
89 Instrument->InstrumentThreadOnly.OnError();
97 Instrument->InstrumentThreadOnly.SetException(std::current_exception());
98 Instrument->InstrumentThreadOnly.OnError();
114 auto Task = std::move(
TaskQueue.front());
175 if (Task->get()->InstrumentDataBaseOnly.KeepFinishedTask())
210 InstrumentException = Exception;
273 auto Task = MakeTask<ArriveAtLatchTask>(Latch);
291 if (!InstrumentDataPtr->GetNumEnqueuedTasks())
294 Task = InstrumentDataPtr->GetTaskFront();
295 if (Task->get()->IsAborting())
297 Task->get()->InstrumentBaseOnly.SetAborted();
302 if (Task->get()->GetDeferUntil() > std::chrono::system_clock::now())
305 Task->
get()->InstrumentBaseOnly.Lock();
308 auto DoContinue = Task->get()->InstrumentBaseOnly.Run(Instance);
329 GetInstrumentData()->InstrumentBaseOnly.SetException(Exception);
334 InstrumentData->InstrumentBaseOnly.IndicateException();
354 catch (
const std::exception& e)
406 if (InstrumentDataPtr->GetNumEnqueuedTasks())
408 InstrumentDataPtr->InstrumentBaseOnly.RemoveAllTasksExceptFront();
409 InstrumentDataPtr->GetTaskFront()->get()->Abort();
414 if (!InstrumentDataPtr->GetException())
417 if (Task && !InstrumentDataPtr->GetException())
418 InstrumentDataPtr->EnqueueTask(std::move(Task));
421 InstrumentDataPtr->InstrumentBaseOnly.CloseQueue();
427 Util::EventLog().
Log(
"An instrument has been terminated whithout cleaning up since the error reported below has occurred while issuing an exit task.",
446 catch (
const std::exception& e)
459 using namespace std::chrono_literals;
469 using namespace std::chrono_literals;
481 InstrumentDataGetter(InstrumentDataGetter)
486 :
RunnableInstance(std::move(Other)), InstrumentDataGetter(Other.InstrumentDataGetter)
497 : CallbackFunc(Other.CallbackFunc), HasBeenCalled(Other.HasBeenCalled)
499 Other.HasBeenCalled =
true;
508 this->operator()(
nullptr, Exception);
539 auto StateCopy =
State.load();
570 return Result.ToTaskHandlingContinuationType();
Implementation of DynExp instrument objects.
~ArriveAtLatchTask()
If the task has been aborted or never executed, the destructor arrives at the latch in order to avoid...
virtual TaskResultType RunChild(InstrumentInstance &Instance) override
Runs the task. Override RunChild() to define a derived task's action(s). Any exception leaving RunChi...
Wrapper holding a pointer to an exception and providing functionality for accessing it....
bool IsError() const
Checks whether the wrapper holds an exception.
TaskResultType RunChild(InstrumentInstance &Instance) override final
Runs the task. Override RunChild() to define a derived task's action(s). Any exception leaving RunChi...
Refer to DynExp::ParamsBase::dispatch_tag.
TaskResultType RunChild(InstrumentInstance &Instance) override final
Runs the task. Override RunChild() to define a derived task's action(s). Any exception leaving RunChi...
Refer to DynExp::ParamsBase::dispatch_tag.
Base class for instruments. Instruments comprise virtual devices (meta instruments) and physial devic...
static auto GetExceptionUnsafe(const InstrumentDataTypeSyncPtrConstType &InstrumentDataPtr)
Getter for InstrumentDataBase::InstrumentException. If InstrumentDataBase::InstrumentException is nul...
bool IsReadyChild() const override final
Returns wheter this Object instance is ready (e.g. it is running or connected to a hardware device) a...
Util::SynchronizedPointer< const InstrumentDataType > InstrumentDataTypeSyncPtrConstType
Alias for the return type of InstrumentBase::GetInstrumentData() const. Data class instances wrapped ...
void ResetImpl(dispatch_tag< RunnableObject >) override final
Refer to DynExp::Object::Reset(). Using tag dispatch mechanism to ensure that ResetImpl() of every de...
virtual bool UpdateAdditionalData()
Determines whether to enqueue update tasks (UpdateTaskBase).
TaskHandlingContinuationType HandleTask(InstrumentInstance &Instance)
Executes and removes the next pending task from the instrument's task queue.
InstrumentBase(const std::thread::id OwnerThreadID, ParamsBasePtrType &&Params)
Constructs an instrument instance.
std::exception_ptr GetExceptionChild(const std::chrono::milliseconds Timeout) const override final
Returns a pointer to the exception which has caused this Object instance to fail.
void UpdateData() const
Enqueues an update task (instance of class UpdateTaskBase).
std::atomic< bool > Initialized
Determines whether the init task (InitTaskBase) has run.
void OnPrepareExit()
This function enables derived classes to enqueue tasks to be executed directly before the final exit ...
void SetException(std::exception_ptr Exception) noexcept
Sets this instrument instance to an error state and tries to store the exception responsible for the ...
void EnqueueArriveAtLatchTask(std::latch &Latch) const
Enqueues a task which arrives at a latch when executed (instance of class ArriveAtLatchTask).
virtual void OnPrepareExitChild() const
This function enables derived classes to enqueue tasks to be executed directly before the final exit ...
virtual std::unique_ptr< InitTaskBase > MakeInitTask() const
Factory function for an init task (InitTaskBase). Override to define the desired initialization task ...
void UpdateDataInternal()
Inserts an update task (UpdateTaskBase) into the instrument's task queue. Override UpdateAdditionalDa...
static constexpr auto GetInstrumentDataTimeoutDefault
Determines the default timeout for GetInstrumentData() to lock the mutex synchronizing the instrument...
void TerminateChild(const std::chrono::milliseconds Timeout) override final
Signals derived classes that terminating the RunnableObject instance's thread is about to be requeste...
virtual void OnErrorChild() const
Derived classes can perform critical shutdown actions after an error has occurred....
void RunChild() override final
Refer to Run().
InstrumentDataTypeSyncPtrType GetInstrumentData(const std::chrono::milliseconds Timeout=GetInstrumentDataTimeoutDefault)
Locks the mutex of the instrument data class instance InstrumentData assigned to this InstrumentBase ...
Util::SynchronizedPointer< InstrumentDataType > InstrumentDataTypeSyncPtrType
Alias for the return type of InstrumentBase::GetInstrumentData(). Data class instances wrapped into U...
virtual bool HandleAdditionalTask()
Determines whether task handling should continue.
InstrumentDataTypeSyncPtrType GetNonConstInstrumentData(const std::chrono::milliseconds Timeout=GetInstrumentDataTimeoutDefault) const
Always allows InstrumentBase to obtain a non-const pointer to the instrument's data - even in const t...
void OnError()
Derived classes can perform critical shutdown actions after an error has occurred....
virtual ~InstrumentBase()=0
virtual std::unique_ptr< ExitTaskBase > MakeExitTask() const
Factory function for an exit task (ExitTaskBase). Override to define the desired deinitialization tas...
virtual std::unique_ptr< UpdateTaskBase > MakeUpdateTask() const
Factory function for an update task (UpdateTaskBase). Override to define the desired update task in d...
TaskHandlingContinuationType
Indicates how an instrument should proceed after handling a task.
const std::unique_ptr< InstrumentDataType > InstrumentData
Instrument data belonging to this InstrumentBase instance.
bool IsInitialized() const
Getter for Initialized.
void NotifyChild() override final
Notify derived classes that some state has changed (e.g. the termination of Thread is requested) and ...
virtual ~InstrumentConfiguratorBase()=0
virtual void ResetImpl(dispatch_tag< InstrumentDataBase >)
Refer to DynExp::InstrumentDataBase::Reset(). Using tag dispatch mechanism to ensure that ResetImpl()...
TaskQueueType TaskQueue
FIFO task queue of the instrument owning this InstrumentDataBase instance.
void CheckError() const
Throws InstrumentException if it is not nullptr using Util::ForwardException().
bool IsQueueClosed() const noexcept
Determines whether the instrument task queue is closed.
void Reset()
Resets the InstrumentDataBase's instance and calls ResetImpl(dispatch_tag<InstrumentDataBase>) subseq...
std::unique_ptr< TaskBase > PopTaskBack()
Removes a task from the back of an instrument's task queue.
void EnqueuePriorityTask(std::unique_ptr< TaskBase > &&Task)
Enqueues a task at the front of an instrument's task queue and notifies the instrument about the new ...
std::atomic< bool > HasException
If set to true, indicates to the main thread that an exception has happened in the instrument thread....
void RemoveAllTasks()
Clears the instrument's task queue.
TaskQueueType::const_iterator TaskQueueIteratorType
Const iterator type to elements of TaskQueueType.
void EnqueueTask(std::unique_ptr< TaskBase > &&Task)
Enqueues a task at the back of an instrument's task queue and notifies the instrument about the new t...
std::unique_ptr< TaskBase > PopTaskFront()
Removes a task from the front of an instrument's task queue.
std::exception_ptr GetException() const noexcept
Getter for InstrumentDataBase::InstrumentException. If InstrumentDataBase::InstrumentException is nul...
Util::OneToOneNotifier NewTaskNotifier
Used to notify the instrument thread about new tasks when enqueuing tasks into the task queue....
void SetException(std::exception_ptr Exception) noexcept
Setter for InstrumentException.
std::exception_ptr InstrumentException
Used to transfer exceptions from the instrument thread to the main thread. Stores the exception respo...
std::unique_ptr< TaskBase > PopFinishedTask()
Removes a task from the front of an instrument's list of finished tasks.
void RemoveAllTasksExceptFront()
Clears the instrument's task queue but keeps the front task (the task with highest priority which is ...
void CheckQueueState(bool CallFromInstrThread) const
Checks whether it is currently allowed to enqueue tasks into the instrument task queue.
void RemoveTaskFromQueue(TaskQueueIteratorType &Task)
Removes a task from the instrument's task queue and inserts it into the instrument's list of finished...
bool QueueClosed
If set to true, no new tasks can be enqueued (useful if an instrument is e.g. stopped).
TaskQueueType FinishedTasks
List of the instrument's finished tasks. Tasks are moved here from TaskQueue after completion.
Refer to ParamsBase::dispatch_tag.
Defines data for a thread belonging to a InstrumentBase instance. Refer to RunnableInstance.
InstrumentInstance(InstrumentBase &Owner, std::promise< void > &&ThreadExitedPromise, const InstrumentBase::InstrumentDataGetterType InstrumentDataGetter)
Constructs a non-empty RunnableInstance instance.
virtual ~InstrumentParamsBase()=0
void EnsureCallFromOwningThread() const
Asserts that the call to this function is performed from the thread which constructed this Object ins...
Refer to ParamsBase::dispatch_tag.
Defines data for a thread belonging to a RunnableObject instance. This data is only accessed by the R...
const Object::ParamsGetterType ParamsGetter
Invoke to obtain the parameters (derived from ParamsBase) of Owner.
Defines an Object which possesses a thread it runs in. The RunnableObject can be started and stopped ...
bool IsCallFromRunnableThread() const
Checks whether Thread's id matches the id of the calling thread. This is thread-safe if the function ...
std::promise< void > MakeThreadExitedPromise()
Helper function to be used by overridden RunChild() functions in derived classes to (re)initialize th...
void MakeThread(ThreadFuncType ThreadFunc, std::unique_ptr< RunnableInstance > &&InstancePtr)
Creates and runs the thread of the RunnableObject instance. Call this function in the derived class o...
static constexpr auto ShortTimeoutDefault
Default timeout e.g. used as a default for calls to InstrumentBase::GetInstrumentData or ModuleBase::...
bool IsExiting() const noexcept
Returns ShouldExit.
void EnsureCallFromRunnableThread() const
Asserts that the call to this function is performed from the RunnableObject instance's thread by call...
bool IsRunning() const noexcept
Returns Running.
Type owning a callback function which is invoked when a task has finished, failed,...
~CallbackType()
Calls operator()() passing nullptr to the first argument of FuncType. Swallows all exceptions possibl...
CallbackType()
Constructs a CallbackType instance with an empty CallbackFunc.
CallbackType CallbackFunc
This callback function is called after the task has finished (either successfully or not) with a poin...
void Lock()
Locks the task to prepare it for execution.
virtual TaskResultType RunChild(InstrumentInstance &Instance)=0
Runs the task. Override RunChild() to define a derived task's action(s). Any exception leaving RunChi...
std::atomic< int > ErrorCode
Holds the error code of an error which occurred during execution of the task function.
std::atomic< TaskState > State
Holds the task's current state. Refer to TaskBase::TaskState.
bool IsLocked() const noexcept
Determines whether the task is locked.
virtual ~TaskBase()=0
The destructor aborts a waiting task setting State to TaskState::Aborted. Then, it calls CallbackFunc...
InstrumentBase::TaskHandlingContinuationType Run(InstrumentInstance &Instance)
Runs the task. Override RunChild() to define a derived task's action(s). Any exception leaving RunChi...
Defines the return type of task functions.
@ Terminate
Task handling should not continue, the instrument should terminate.
@ Continue
Task handling should continue, the instrument does not terminate.
constexpr InstrumentBase::TaskHandlingContinuationType ToTaskHandlingContinuationType() const noexcept
Converts Continue to InstrumentBase::TaskHandlingContinuationType.
const ContinuationType Continue
Determines whether an instrument should terminate after handling a task.
TaskResultType RunChild(InstrumentInstance &Instance) override final
Runs the task. Override RunChild() to define a derived task's action(s). Any exception leaving RunChi...
Refer to DynExp::ParamsBase::dispatch_tag.
Wraps a member function of some object and stores its default arguments. Moving from CallableMemberWr...
void Log(const std::string &Message, const ErrorType Type=ErrorType::Info, const size_t Line=0, const std::string &Function="", const std::string &File="", const int ErrorCode=0, const std::stacktrace &Trace={}) noexcept
Logs an event from information specified manually.
DynExp exceptions are derived from this class. It contains basic information about the cause of the e...
const int ErrorCode
DynExp error code from DynExpErrorCodes::DynExpErrorCodes
An invalid argument like a null pointer has been passed to a function.
An operation cannot be performed currently since the related object is in an invalid state like an er...
void Notify()
Set notification to stop waiting (sets EventOccurred to true).
Pointer to lock a class derived from ISynchronizedPointerLockable for synchronizing between threads....
auto get() const noexcept
Returns the managed (locked) object.
DynExp's main namespace contains the implementation of DynExp including classes to manage resources (...
int InstrumentThreadMain(std::unique_ptr< RunnableInstance > &&InstancePtr, RunnableObject *BaseObject)
Instruments run in their own thread. This is the instrument thread's main function.
std::unique_ptr< ParamsBase > ParamsBasePtrType
Alias for a pointer to the parameter system base class ParamsBase.
T::ParamsType * dynamic_Params_cast(ParamsBasePtrType::element_type *Params)
Casts the parameter base class to a derived Object's parameter class.
void ForwardException(std::exception_ptr e)
Wraps the exception passed to the function in a ForwardedException and throws the ForwardedException....
EventLogger & EventLog()
This function holds a static EventLogger instance and returns a reference to it. DynExp uses only one...
Accumulates include statements to provide a precompiled header.