RTI Connext Modern C++ API  Version 6.0.1
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
rti::core::cond::AsyncWaitSet Class Reference

<<interface>> A class for dispatching dds::core::cond::Condition objects using separate threads of execution. You can see this class as an extension of a dds::core::cond::WaitSet that allows asynchronously waiting for the attached dds::core::cond::Condition objects to trigger and provide a notification by calling dds::core::cond::Condition::dispatch. More...

#include <rti/core/cond/AsyncWaitSet.hpp>

Inheritance diagram for rti::core::cond::AsyncWaitSet:
dds::core::Reference< AsyncWaitSetImpl >

Public Member Functions

 AsyncWaitSet ()
 Constructor without arguments that create an rti::core::cond::AsyncWaitSet with default property.
 
 AsyncWaitSet (const AsyncWaitSetProperty &the_property)
 Single-argument constructor that allows creating a a rti::core::cond::AsyncWaitSet with custom behavior.
 
 AsyncWaitSet (const AsyncWaitSetProperty &the_property, AsyncWaitSetListener *listener)
 Constructor that allows specifying a rti::core::cond::AsyncWaitSetListener.
 
void start ()
 Initiates the asynchronous wait on this rti::core::cond::AsyncWaitSet.
 
void start (AsyncWaitSetCompletionToken completion_token)
 Initiates the asynchronous wait on this rti::core::cond::AsyncWaitSet.
 
void stop ()
 Initiates the stop procedure on this rti::core::cond::AsyncWaitSet that will stop the asynchronous wait.
 
void stop (AsyncWaitSetCompletionToken completion_token)
 Initiates the stop procedure on this rti::core::cond::AsyncWaitSet that will stop the asynchronous wait.
 
AsyncWaitSetattach_condition (dds::core::cond::Condition condition)
 Attaches the specified dds::core::cond::Condition to this rti::core::cond::AsyncWaitSet.
 
AsyncWaitSetattach_condition (dds::core::cond::Condition condition, AsyncWaitSetCompletionToken completion_token)
 Attaches the specified dds::core::cond::Condition to this rti::core::cond::AsyncWaitSet.
 
AsyncWaitSetdetach_condition (dds::core::cond::Condition condition)
 Deaches the specified dds::core::cond::Condition from this rti::core::cond::AsyncWaitSet.
 
AsyncWaitSetdetach_condition (dds::core::cond::Condition condition, AsyncWaitSetCompletionToken completion_token)
 Detaches the specified dds::core::cond::Condition from this rti::core::cond::AsyncWaitSet.
 
AsyncWaitSetoperator+= (dds::core::cond::Condition condition)
 Attaches the specified dds::core::cond::Condition to this rti::core::cond::AsyncWaitSet.
 
AsyncWaitSetoperator-= (dds::core::cond::Condition condition)
 Deaches the specified dds::core::cond::Condition from this rti::core::cond::AsyncWaitSet.
 
void unlock_condition (dds::core::cond::Condition condition)
 Allows the dds::core::cond::Condition under dispatch to be available for concurrent dispatch from another thread from the pool.
 
AsyncWaitSetProperty property ()
 Retrieves the rti::core::cond::AsyncWaitSetProperty_t configuration of the associated rti::core::cond::AsyncWaitSet.
 
ConditionSeq conditions () const
 Returns the list of attached dds::core::cond::Condition (s).
 
ConditionSeq & conditions (ConditionSeq &attached_conditions) const
 Retrieves the list of attached dds::core::cond::Condition (s).
 

Detailed Description

<<interface>> A class for dispatching dds::core::cond::Condition objects using separate threads of execution. You can see this class as an extension of a dds::core::cond::WaitSet that allows asynchronously waiting for the attached dds::core::cond::Condition objects to trigger and provide a notification by calling dds::core::cond::Condition::dispatch.

rti::core::cond::AsyncWaitSet provides a proactive model to process application events through dds::core::cond::Condition objects. rti::core::cond::AsyncWaitSet owns a pool of threads to asynchronously wait for the attached dds::core::cond::Condition objects to trigger and dispatch them upon wakeup. The asynchronous behavior is the main key different with regards to the dds::core::cond::WaitSet.

The class diagram and its collaborators is shown below:

DDSAsyncWaitSet.png
rti::core::cond::AsyncWaitSet

AsyncWaitSet Thread Orchestration

rti::core::cond::AsyncWaitSet internally applies a leader-follower pattern for the orchestration of the thread pool. Once a rti::core::cond::AsyncWaitSet starts, it will create the thread pool of M threads from which only one thread will become the Leader thread, and remaining threads will become the Followers, where:

DDSAsyncWaitSet_leader-follower.png
Thread orchestration in a rti::core::cond::AsyncWaitSet

This behavior implies the following considerations:

rti::core::cond::AsyncWaitSet has a built-in dispatcher that guarantees fairness and avoids starvation of dds::core::cond::Condition objects. By applying a round-robin distribution policy, each attached and active dds::core::cond::Condition is dispatched within a finite period of time, assuming the functor handler always return control after the dds::core::cond::Condition::dispatch operation.

AsyncWaitSet Thread Safety

A key aspect of the rti::core::cond::AsyncWaitSet is the thread safety. rti::core::cond::AsyncWaitSet interface is thread safe, so you can concurrently call any operation on the rti::core::cond::AsyncWaitSet object from multiple threads in your application.

Furthermore, rti::core::cond::AsyncWaitSet also safely interacts with its own thread pool. Internally, the rti::core::cond::AsyncWaitSet applies the asynchronous completion token pattern to perform activities that involve synchronization with the thread pool.

For instance to detach a dds::core::cond::Condition, the rti::core::cond::AsyncWaitSet generates an internal request to its thread pool to process it. As soon as the detachment completes, the thread pool provides the notification through an associated completion token.

Note
The asynchronous completion token behavior only takes place if the rti::core::cond::AsyncWaitSet is started. Otherwise the internal request will be directly executed by the calling thread.

For a finer control on this behavior, each rti::core::cond::AsyncWaitSet operation where this applies comes in two flavors:

Condition Locking

rti::core::cond::AsyncWaitSet incorporates a safety mechanism that prevents calling dds::core::cond::Condition::dispatch concurrently. rti::core::cond::AsyncWaitSet locks the dds::core::cond::Condition while a processor thread is dispatching it so no other thread within the pool can dispatch it again.

This mechanism ensures not only unexpected concurrent dispatch of a dds::core::cond::Condition but also spurious thread activity. Because it is responsibility of your application to reset the Condition trigger, there is a period of time in which the dispatched condition may remain active, causing the rti::core::cond::AsyncWaitSet to enter in a continous immediate wakeup from the wait. This behavior typically leads to thread hogging and high CPU usage.

Nevertheless, your application may still want to receive concurrent and controlled dispatch notifications. rti::core::cond::AsyncWaitSet will still allows you to unlock a dds::core::cond::Condition so any other available thread can dispatch the same condition concurrently while preventing the above mentioned problems. You can achive this by calling rti::core::cond::AsyncWaitSet::unlock_condition on the Condition being dispatched within the dispatch callback. Note that the AsyncWaitSet locks a Condition each time it dispatches it. Hence you need to unlock the Condition each time you want to enable a concurrent dispatch.

AsyncWaitSet Events and Resources

Besides dds::core::cond::Condition processing, you can listen to other kind of internal events related to the rti::core::cond::AsyncWaitSet and its thread pool by means of the rti::core::cond::AsyncWaitSetListener.

rti::core::cond::AsyncWaitSet exposes operations to start and stop the asynchronous wait, which involves the creation and deletion of the thread pool respectively.

rti::core::cond::AsyncWaitSet relies on thread-specific storage to provide the described functionality. Each application thread that calls an operation on a rti::core::cond::AsyncWaitSet will generate resources that will be associated with such thread. You can free these resources upon thread termination by calling DomainParticipantFactory::unregister_thread.

MT Safety:
Safe.
See Also
dds::core::cond::WaitSet
dds::core::cond::Condition
rti::core::cond::AsyncWaitSetListener
rti::core::cond::AsyncWaitSetCompletionToken.
rti::core::cond::AsyncWaitSetProperty_t

Constructor & Destructor Documentation

rti::core::cond::AsyncWaitSet::AsyncWaitSet ( const AsyncWaitSetProperty the_property)
inline

Single-argument constructor that allows creating a a rti::core::cond::AsyncWaitSet with custom behavior.

You can provide rti::core::cond::AsyncWaitSetProperty::AsyncWaitSetProperty() as property to create an rti::core::cond::AsyncWaitSet with default bheavior.

The rti::core::cond::AsyncWaitSet is created with no listener installed.

Parameters
the_property<<in>> configuration rti::core::cond::AsyncWaitSetProperty_t
Returns
A new rti::core::cond::AsyncWaitSet or NULL if one could not be allocated.
rti::core::cond::AsyncWaitSet::AsyncWaitSet ( const AsyncWaitSetProperty the_property,
AsyncWaitSetListener listener 
)
inline

Constructor that allows specifying a rti::core::cond::AsyncWaitSetListener.

Creates a new rti::core::cond::AsyncWaitSet with the specified property rti::core::cond::AsyncWaitSetProperty_t and rti::core::cond::AsyncWaitSetListener.

Parameters
the_property<<in>> configuration rti::core::cond::AsyncWaitSetProperty_t
listener<<in>> the rti::core::cond::AsyncWaitSetListener. Cannot be NULL.
Returns
A new rti::core::cond::AsyncWaitSet or NULL if one could not be allocated.

Member Function Documentation

void rti::core::cond::AsyncWaitSet::start ( )
inline

Initiates the asynchronous wait on this rti::core::cond::AsyncWaitSet.

This operation blocks until the start request completes. Upon successful return, it is guaranteed that this rti::core::cond::AsyncWaitSet has initiated the asynchronous wait and dispatch.

Exceptions
Oneof the Standard Exceptions
See Also
rti::core::cond::AsyncWaitSet::start(AsyncWaitSetCompletionToken)
rti::core::cond::AsyncWaitSet::stop
void rti::core::cond::AsyncWaitSet::start ( AsyncWaitSetCompletionToken  completion_token)
inline

Initiates the asynchronous wait on this rti::core::cond::AsyncWaitSet.

If this operation succeeds, a start request has been scheduled and your application can use the provided completion_token to wait for this rti::core::cond::AsyncWaitSet to process the request. If the rti::core::cond::AsyncWaitSetCompletionToken::wait operation returns successfully, it is guranteed that the thread pool has been created and the leader thread is waiting for the attached dds::core::cond::Condition to trigger.

Once this rti::core::cond::AsyncWaitSet is started, attached dds::core::cond::Condition will be dispatched through the dds::core::cond::Condition::dispatch operation when they trigger.

The start procedure causes the rti::core::cond::AsyncWaitSet to spawn all the threads within the thread pool, which involves the underlying operating system to allocate the associated thread stack and context for each thread. If a rti::core::cond::AsyncWaitSetListener is installed, this rti::core::cond::AsyncWaitSet will sequentially invoke the rti::core::cond::AsyncWaitSetListener::on_thread_spawned once per spwaned thread.

A rti::core::cond::AsyncWaitSet can be restarted after a stop. If this rti::core::cond::AsyncWaitSet is already started, this operation will return immediately with success, and waiting on the completion_token will also return immediately with success.

Parameters
completion_token<<inout>> a valid rti::core::cond::AsyncWaitSetCompletionToken instance that can be used by your application to wait for the start request to complete. You can provide the special sentinel rti::core::cond::AsyncWaitSetCompletionToken::Ignore().
Exceptions
Oneof the Standard Exceptions
See Also
rti::core::cond::AsyncWaitSet::start
rti::core::cond::AsyncWaitSet::start(AsyncWaitSetCompletionToken)
dds::core::cond::WaitSet::wait
void rti::core::cond::AsyncWaitSet::stop ( )
inline

Initiates the stop procedure on this rti::core::cond::AsyncWaitSet that will stop the asynchronous wait.

This operation will block until the stop request completes. Upon successful return, it is guaranteed that this rti::core::cond::AsyncWaitSet stopped the asynchronous wait and dispatch.

Exceptions
Oneof the Standard Exceptions
See Also
rti::core::cond::AsyncWaitSet::start(AsyncWaitSetCompletionToken)
rti::core::cond::AsyncWaitSet::stop
void rti::core::cond::AsyncWaitSet::stop ( AsyncWaitSetCompletionToken  completion_token)
inline

Initiates the stop procedure on this rti::core::cond::AsyncWaitSet that will stop the asynchronous wait.

If this operation succeeds, a stop request has been scheduled and your application can use the provided completion_token to wait for this rti::core::cond::AsyncWaitSet to process the request. If the rti::core::cond::AsyncWaitSetCompletionToken::wait operation returns successfully, it is guranteed that the thread pool has been deleted and this rti::core::cond::AsyncWaitSet no longer process any of the attached dds::core::cond::Condition objects.

Once this rti::core::cond::AsyncWaitSet is stopped, the dds::core::cond::Condition::dispatch will no longer be called on any of the attached dds::core::cond::Condition, no matter what their trigger value is.

The stop procedure causes the rti::core::cond::AsyncWaitSet to delete all the threads within the thread pool, which involves the underlying operating system to release the associated thread stack and context of each thread. If a rti::core::cond::AsyncWaitSetListener is installed, this rti::core::cond::AsyncWaitSet will sequentially invoke the rti::core::cond::AsyncWaitSetListener::on_thread_deleted once per deleted thread.

If this rti::core::cond::AsyncWaitSet is already stopped, this operation will return immediately with success, and waiting on the completion_token will also return immediately with success.

Parameters
completion_token<<inout>> a valid rti::core::cond::AsyncWaitSetCompletionToken instance that can be used by your application to wait for the stop request to complete. You can provide the special sentinel rti::core::cond::AsyncWaitSetCompletionToken::Ignore().
Exceptions
Oneof the Standard Exceptions
See Also
rti::core::cond::AsyncWaitSet::stop
rti::core::cond::AsyncWaitSet::start(AsyncWaitSetCompletionToken)
AsyncWaitSet& rti::core::cond::AsyncWaitSet::attach_condition ( dds::core::cond::Condition  condition)
inline

Attaches the specified dds::core::cond::Condition to this rti::core::cond::AsyncWaitSet.

This operation will block until the attach request completes. Upon successful return, it is guaranteed that the specified dds::core::cond::Condition is attached.

Parameters
condition<<in>> dds::core::cond::Condition to be attached.
Exceptions
Oneof the Standard Exceptions
See Also
rti::core::cond::AsyncWaitSet::attach_condition(dds::core::cond::Condition, AsyncWaitSetCompletionToken)
AsyncWaitSet& rti::core::cond::AsyncWaitSet::attach_condition ( dds::core::cond::Condition  condition,
AsyncWaitSetCompletionToken  completion_token 
)
inline

Attaches the specified dds::core::cond::Condition to this rti::core::cond::AsyncWaitSet.

If this operation succeeds, an attach request has been scheduled and your application can use the output parameter completion_token to wait for this rti::core::cond::AsyncWaitSet to process the request. rti::core::cond::AsyncWaitSetCompletionToken::wait operation returns successfully, it is guaranteed that the dds::core::cond::Condition is attached to this rti::core::cond::AsyncWaitSet.

Once the dds::core::cond::Condition is attached, its trigger value may cause the leader thread of the rti::core::cond::AsyncWaitSet to wake up call the dds::core::cond::Condition::dispatch operation.

dds::core::cond::Condition may be attached at any time independently of the state of the rti::core::cond::AsyncWaitSet.

Parameters
condition<<in>> dds::core::cond::Condition to be attached.
completion_token<<inout>> a valid rti::core::cond::AsyncWaitSetCompletionToken instance that can be used by your application to wait for the attach request to complete. You can provide the special sentinel rti::core::cond::AsyncWaitSetCompletionToken::Ignore().
Exceptions
Oneof the Standard Exceptions
See Also
rti::core::cond::AsyncWaitSet::attach_condition
rti::core::cond::AsyncWaitSet::detach_condition(dds::core::cond::Condition, AsyncWaitSetCompletionToken)
rti::core::cond::AsyncWaitSetCompletionToken::wait
AsyncWaitSet& rti::core::cond::AsyncWaitSet::detach_condition ( dds::core::cond::Condition  condition)
inline

Deaches the specified dds::core::cond::Condition from this rti::core::cond::AsyncWaitSet.

This operation blocks until the detach request completes. Upon successful return, it is guaranteed that the specified dds::core::cond::Condition is detached.

Parameters
condition<<in>> dds::core::cond::Condition to be detached.
Exceptions
Oneof the Standard Exceptions
See Also
rti::core::cond::AsyncWaitSet::detach_condition(dds::core::cond::Condition, AsyncWaitSetCompletionToken)
AsyncWaitSet& rti::core::cond::AsyncWaitSet::detach_condition ( dds::core::cond::Condition  condition,
AsyncWaitSetCompletionToken  completion_token 
)
inline

Detaches the specified dds::core::cond::Condition from this rti::core::cond::AsyncWaitSet.

If this operation succeeds, a detach request has been scheduled and your application can use the provided completion_token to wait for this rti::core::cond::AsyncWaitSet to process the request. If the rti::core::cond::AsyncWaitSetCompletionToken::wait operation returns successfully, it is guaranteed that the dds::core::cond::Condition is detached from this rti::core::cond::AsyncWaitSet.

Once the dds::core::cond::Condition is detached, it is guaranteed that the rti::core::cond::AsyncWaitSet will no longer process it so it is safe for your application to release any resources associated with the detached dds::core::cond::Condition.

dds::core::cond::Condition may be detached at any time independently of the state of the rti::core::cond::AsyncWaitSet.

Parameters
condition<<in>> dds::core::cond::Condition to be detached.
completion_token<<inout>> a valid rti::core::cond::AsyncWaitSetCompletionToken instance that can be used by your application to wait for the detach request to complete. You can provide the special sentinel rti::core::cond::AsyncWaitSetCompletionToken::Ignore().
Exceptions
Oneof the Standard Exceptions
See Also
rti::core::cond::AsyncWaitSet::detach_condition
rti::core::cond::AsyncWaitSet::attach_condition(dds::core::cond::Condition, AsyncWaitSetCompletionToken)
rti::core::cond::AsyncWaitSetCompletionToken::wait
AsyncWaitSet& rti::core::cond::AsyncWaitSet::operator+= ( dds::core::cond::Condition  condition)
inline

Attaches the specified dds::core::cond::Condition to this rti::core::cond::AsyncWaitSet.

This operation will block until the attach request completes. Upon successful return, it is guaranteed that the specified dds::core::cond::Condition is attached.

Parameters
condition<<in>> dds::core::cond::Condition to be attached.
Exceptions
Oneof the Standard Exceptions
See Also
rti::core::cond::AsyncWaitSet::attach_condition(dds::core::cond::Condition, AsyncWaitSetCompletionToken)
AsyncWaitSet& rti::core::cond::AsyncWaitSet::operator-= ( dds::core::cond::Condition  condition)
inline

Deaches the specified dds::core::cond::Condition from this rti::core::cond::AsyncWaitSet.

This operation blocks until the detach request completes. Upon successful return, it is guaranteed that the specified dds::core::cond::Condition is detached.

Parameters
condition<<in>> dds::core::cond::Condition to be detached.
Exceptions
Oneof the Standard Exceptions
See Also
rti::core::cond::AsyncWaitSet::detach_condition(dds::core::cond::Condition, AsyncWaitSetCompletionToken)
void rti::core::cond::AsyncWaitSet::unlock_condition ( dds::core::cond::Condition  condition)
inline

Allows the dds::core::cond::Condition under dispatch to be available for concurrent dispatch from another thread from the pool.

This operation can be called from the dispatch callback of the dds::core::cond::Condition this rti::core::cond::AsyncWaitSet is dispatching. After succesfully calling this operation, if the dds::core::cond::Condition becomes active this rti::core::cond::AsyncWaitSet is allowed to dispatch it again from any available thread from the pool.

You may call this operation any time you need the same dds::core::cond::Condition to be dispatched concurrently.

This operation will fail with dds::core::PreconditionNotMetError if you call it from a different context than the dispatch callback or on a different dds::core::cond::Condition.

Exceptions
Oneof the Standard Exceptions
AsyncWaitSetProperty rti::core::cond::AsyncWaitSet::property ( )
inline

Retrieves the rti::core::cond::AsyncWaitSetProperty_t configuration of the associated rti::core::cond::AsyncWaitSet.

Exceptions
Oneof the Standard Exceptions
ConditionSeq rti::core::cond::AsyncWaitSet::conditions ( ) const
inline

Returns the list of attached dds::core::cond::Condition (s).

ConditionSeq& rti::core::cond::AsyncWaitSet::conditions ( ConditionSeq &  attached_conditions) const
inline

Retrieves the list of attached dds::core::cond::Condition (s).

Parameters
attached_conditions<<inout>> a ConditionSeq object where the list of attached conditions will be returned.
Exceptions
Oneof the Standard Exceptions
See Also
rti::core::cond::AsyncWaitSet::attach_condition
rti::core::cond::AsyncWaitSet::detach_condition

RTI Connext Modern C++ API Version 6.0.1 Copyright © Sat Nov 23 2019 Real-Time Innovations, Inc