Taskolib  1.3.3
Public Member Functions | Private Member Functions | Private Attributes | List of all members
task::Executor Class Reference

Detailed Description

An executor runs a copy of a given Sequence (or just a single step within it) in a separate thread, receives messages from it, and updates the local instance of the Sequence accordingly.

A sequence is started in a separate thread with run_asynchronously() and a single step can be started in isolation with run_single_step_asynchronously(). Afterwards, the main thread must periodically call update() to process messages from the thread. The thread has finished when update() returns false.

Sequence sequence = load_sequence();
Context context;
// Start executing a copy of the sequence in a separate thread
ex.run_asynchronously(sequence, context);
// Periodically call update() to bring our local copy of the sequence in sync with the
// other thread: This updates timestamps and "under execution" flags. Once the sequence
// has finished, update() returns false and the thread is joined automatically.
while (ex.update(sequence))
sleep(0.1s);
Executor()
Construct an Executor.
Definition: Executor.cc:62
Note
Calling update() in the main thread is mandatory to ensure that the sequence in the worker thread can make progress. This is because the message queue for communication between the threads has only a limited capacity, and execution is paused once it is full. Only calls to update() take messages out of the queue again.

#include <Executor.h>

Public Member Functions

 Executor ()
 Construct an Executor. More...
 
 Executor (Executor const &)=delete
 
Executoroperator= (Executor const &)=delete
 
 Executor (Executor &&)=default
 
Executoroperator= (Executor &&)=default
 
 ~Executor ()
 
void cancel ()
 Terminate a running sequence. More...
 
void cancel (Sequence &sequence)
 Terminate a running sequence. More...
 
void run_asynchronously (Sequence &sequence, Context context)
 Start a copy of the given sequence in a separate thread. More...
 
void run_single_step_asynchronously (Sequence &sequence, Context context, StepIndex step_index)
 Start a single step of the given sequence in a separate thread. More...
 
bool update (Sequence &sequence)
 Update the local copy of the sequence from messages that have arrived from the execution thread. More...
 
VariableTable get_context_variables ()
 Retrieve the variables stored in the context. More...
 

Private Member Functions

void launch_async_execution (Sequence &sequence, Context context, OptionalStepIndex step_index)
 Start a sequence- or single-step-execution function in a separate thread. More...
 
bool is_busy ()
 Determine if the executor is currently running a sequence in a separate thread. More...
 

Private Attributes

std::shared_ptr< CommChannelcomm_channel_
 Communications channel between the main thread and the executing thread. More...
 
std::future< VariableTablefuture_
 A future for the result of the execution thread. More...
 
Context context_
 A local copy of the context that was used to start the last sequence. More...
 

Constructor & Destructor Documentation

◆ Executor() [1/3]

task::Executor::Executor ( )

Construct an Executor.

◆ Executor() [2/3]

task::Executor::Executor ( Executor const &  )
delete

◆ Executor() [3/3]

task::Executor::Executor ( Executor &&  )
default

◆ ~Executor()

task::Executor::~Executor ( )
inline

References cancel().

Member Function Documentation

◆ cancel() [1/2]

void task::Executor::cancel ( )

Terminate a running sequence.

If a sequence is running in a separate thread, this call sends a termination request and waits for the thread to shut down. If no sequence is currently running, the call has no effect. An associated Sequence will not be updated and all messages are lost. Usually you should call cancel(Sequence& sequence).

References comm_channel_, context_, future_, and task::Context::variables.

Referenced by ~Executor().

◆ cancel() [2/2]

void task::Executor::cancel ( Sequence sequence)

Terminate a running sequence.

If a sequence is running in a separate thread, this call sends a termination request and waits for the thread to shut down. If no sequence is currently running, the call has no effect. The associated Sequence will be updated with all pending messages.

References comm_channel_, context_, future_, update(), and task::Context::variables.

◆ get_context_variables()

VariableTable task::Executor::get_context_variables ( )
inline

Retrieve the variables stored in the context.

After a sequence has run the context variables can be retrieved for inspection. Note that the variables are only updated after the Sequence has stopped. Use this only after update() returns false (is_busy() == false).

Returns
the context variable mapping.

References context_, and task::Context::variables.

◆ is_busy()

bool task::Executor::is_busy ( )
private

Determine if the executor is currently running a sequence in a separate thread.

Returns
true if a sequence is being executed or false otherwise.
Note
This function does not retrieve any messages from the message queue, but it does join the worker thread if it has finished its sequence.

References context_, future_, and task::Context::variables.

Referenced by update().

◆ launch_async_execution()

void task::Executor::launch_async_execution ( Sequence sequence,
Context  context,
OptionalStepIndex  step_index 
)
private

Start a sequence- or single-step-execution function in a separate thread.

Parameters
sequenceThe Sequence to be started or the parent sequence of the step
contextThe execution Context
comm_channelShared pointer to a CommChannel for communication (can be null)
step_indexFor single-step execution, this is the index of the step to be started; for sequence execution, it has no meaning.
Exceptions
Erroris thrown if the executor is already busy. The function can also throw any exception from std::async if the thread cannot be created.

References comm_channel_, context_, future_, task::Context::message_callback_function, task::Sequence::set_error(), and task::Sequence::set_running().

Referenced by run_asynchronously(), and run_single_step_asynchronously().

◆ operator=() [1/2]

Executor& task::Executor::operator= ( Executor &&  )
default

◆ operator=() [2/2]

Executor& task::Executor::operator= ( Executor const &  )
delete

◆ run_asynchronously()

void task::Executor::run_asynchronously ( Sequence sequence,
Context  context 
)

Start a copy of the given sequence in a separate thread.

The given sequence is updated in this thread whenever update() is called.

Parameters
sequenceReference to the sequence to be executed; This sequence is marked as is_running(), but the actual execution takes place on a copy in a separate thread.
contextThe context in which the sequence should be executed.
Exceptions
Erroris thrown if this executor is still busy running another sequence.

References launch_async_execution().

◆ run_single_step_asynchronously()

void task::Executor::run_single_step_asynchronously ( Sequence sequence,
Context  context,
StepIndex  step_index 
)

Start a single step of the given sequence in a separate thread.

The given sequence is updated in this thread whenever update() is called.

Parameters
sequenceReference to the sequence containing the step to be executed; This sequence is marked as is_running(), but the actual execution takes place on a copy in a separate thread.
contextThe context in which the step should be executed
step_indexThe index of the step to be executed
Exceptions
Erroris thrown if this executor is still busy running another sequence or if the step index is invalid.

References launch_async_execution(), and task::Sequence::size().

◆ update()

bool task::Executor::update ( Sequence sequence)

Member Data Documentation

◆ comm_channel_

std::shared_ptr<CommChannel> task::Executor::comm_channel_
private

Communications channel between the main thread and the executing thread.

It must stay at a fixed address so both threads can access it even if the Executor object is moved. Both the main thread and the worker thread have one shared_ptr to the channel.

Referenced by cancel(), launch_async_execution(), and update().

◆ context_

Context task::Executor::context_
private

A local copy of the context that was used to start the last sequence.

Its output callbacks are used to produce "console" and logging output. After the Sequence finished it contains the processed context.

Referenced by cancel(), get_context_variables(), is_busy(), launch_async_execution(), and update().

◆ future_

std::future<VariableTable> task::Executor::future_
private

A future for the result of the execution thread.

Once the thread has joined, it contains the context variables from the executed sequence.

Referenced by cancel(), is_busy(), and launch_async_execution().


The documentation for this class was generated from the following files: