coral
A C++ library for distributed co-simulation
|
Creates and controls a background communications thread. More...
#include "coral/async.hpp"
Public Member Functions | |
CommThread () | |
Creates the background thread. More... | |
~CommThread () CORAL_NOEXCEPT | |
If the CommThread object is still active, shuts down the background thread and waits for it to terminate. More... | |
CommThread (CommThread &&other) CORAL_NOEXCEPT | |
Move constructor. More... | |
CommThread & | operator= (CommThread &&other) CORAL_NOEXCEPT |
Move assignment operator. More... | |
template<typename Result > | |
std::future< Result > | Execute (typename CommThreadTask< StackData, Result >::Type task) |
Executes a task asynchronously in the background thread. More... | |
void | Shutdown () |
Terminates the background thread in a controlled manner. More... | |
bool | Active () const CORAL_NOEXCEPT |
Returns whether the CommThread object is active. More... | |
Creates and controls a background communications thread.
The constructor of this class creates a new thread whose lifetime is tied to that of the constructed object (i.e., the destructor will wait for the background thread to complete before returning.) This thread can be used to execute arbitrary code, but its primary design purpose is to run event-based communications code based on coral::net::Reactor. The thread therefore has a dedicated Reactor
object, a reference to which is passed to all functions that are executed in it.
To execute tasks in the background thread, use the Execute() method. Results and exceptions from such functions should be transferred to the foreground thread using the std::future / std::promise mechanism.
The background thread may have a dedicated object of type StackData
. This is located on that thread's stack, and can be used to hold objects persistently across Execute() calls. The StackData
object does not move in memory, and its lifetime ends before that of the Reactor
. A reference to this object is passed to each function that is executed in the background thread. StackData
may be void
, in which case no object is ever created, and no reference is passed to the executed functions.
Any exceptions that are thrown in the background thread (as opposed to being reported using a promise) will cause the thread to terminate. This is true both for exceptions that escape functions which are executed with Execute() and for those thrown in code which is executed indirectly as a result of reactor events. If this happens, a subsequent call to Execute() or Shutdown() will throw a CommThreadDead exception. The original exception can be obtained from this object.
After construction, the CommThread object is in the "active" state, where Active() returns true
. It remains in this state until one of the following happens, after which it is "inactive" and Active() returns false
:
StackData | The type used for an object that holds stack data persistently across function calls in the background thread, or void if no such object is needed. |
|
explicit |
Creates the background thread.
Active() == true
coral::async::CommThread< StackData >::~CommThread | ( | ) |
If the CommThread object is still active, shuts down the background thread and waits for it to terminate.
The destructor calls Shutdown() to terminate the thread, but it will silently ignore any exceptions thrown by that function. Therefore, it is usually recommended to call Shutdown() manually before destruction, in order to catch any errors that might have occurred in the background thread.
coral::async::CommThread< StackData >::CommThread | ( | CommThread< StackData > && | other | ) |
Move constructor.
other.Active() == false
bool coral::async::CommThread< StackData >::Active | ( | ) | const |
Returns whether the CommThread object is active.
If this function returns false
, there is no background thread associated with this object. It may have been terminated, or ownership of it may have been transferred to another CommThread object by a move operation.
The converse is not necessarily true, however: Even if Active() returns true
, the thread may still have terminated due to an exception. The only way to discover whether this is the case is to attempt to run Execute() or Shutdown() and see if CommThreadDead is thrown. If this happens, Active() will return false
afterwards.
std::future< Result > coral::async::CommThread< StackData >::Execute | ( | typename CommThreadTask< StackData, Result >::Type | task | ) |
Executes a task asynchronously in the background thread.
This function returns a std::future that shares its state with the std::promise object passed to the task
function. The promise should be used to report results or errors. This may be done immediately, in the body of the task
function, or it may be done at a later time by registering a reactor event.
A reference to the background thread's coral::net::Reactor object is also passed to task
. Do not call coral::net::Reactor::Stop() on this object to terminate the thread; this will lead to unspecified behaviour. Instead, use Shutdown() to terminate the thread in a controlled manner.
Finally, if the type parameter StackData
is not void
, the function also receives a reference to an object of the given type. This object is located on the background thread's stack, and thus persists across function calls.
See CommThreadTask for more information about the type and signature of the task
function.
Any exceptions that are thrown and allowed to escape from task
will cause the background thread to terminate, and a subsequent call to Execute() or Shutdown() will throw a CommThreadDead exception, rendering the CommThread object in an inactive state.
std::future
. Thus, if an exception is thrown in the background thread when there are any unfulfilled promises, calls to std::future::get() will block indefinitely.Result | The type of the function's "return value". The function will receive an object of type std::promise<Result> which it can use to return the value (or an exception). Result may be void , in which case the promise is simply used to report whether the task was completed successfully. |
[in] | task | A function to be executed in the background thread. |
task
function. CommThreadDead | If the background thread has terminated unexpectedly due to an exception. |
Active() == true
CommThread< StackData > & coral::async::CommThread< StackData >::operator= | ( | CommThread< StackData > && | other | ) |
Move assignment operator.
other.Active() == false
void coral::async::CommThread< StackData >::Shutdown | ( | ) |
Terminates the background thread in a controlled manner.
This function will block until the background thread has terminated. After it returns, the CommThread object will be in the "inactive" state.
CommThreadDead | If the background thread has terminated unexpectedly due to an exception, either before this function was called or during the shutdown procedure. (The latter should usually not happen, as destructors are supposed to be noexcept .) |
Active() == true
Active() == false