RTI Connext Traditional C++ API  Version 7.0.0

A class for dispatching DDSCondition objects using separate threads of execution. You can see this class as an extension of a DDSWaitSet that allows asynchronously waiting for the attached DDSCondition objects to trigger and provide a notification by calling DDSCondition::dispatch. More...

Public Member Functions

virtual DDS_ReturnCode_t start ()
 Initiates the asynchronous wait on this DDSAsyncWaitSet. More...
 
virtual DDS_ReturnCode_t start_with_completion_token (DDSAsyncWaitSetCompletionToken *completion_token)
 Initiates the asynchronous wait on this DDSAsyncWaitSet. More...
 
virtual DDS_ReturnCode_t stop ()
 Initiates the stop procedure on this DDSAsyncWaitSet that will stop the asynchronous wait. More...
 
virtual DDS_ReturnCode_t stop_with_completion_token (DDSAsyncWaitSetCompletionToken *completion_token)
 Initiates the stop procedure on this DDSAsyncWaitSet that will stop the asynchronous wait. More...
 
virtual DDS_ReturnCode_t attach_condition (DDSCondition *condition)
 Attaches the specified DDSCondition to this DDSAsyncWaitSet. More...
 
virtual DDS_ReturnCode_t detach_condition (DDSCondition *condition)
 Deaches the specified DDSCondition from this DDSAsyncWaitSet. More...
 
virtual DDS_ReturnCode_t attach_condition_with_completion_token (DDSCondition *condition, DDSAsyncWaitSetCompletionToken *completion_token)
 Attaches the specified DDSCondition to this DDSAsyncWaitSet. More...
 
virtual DDS_ReturnCode_t detach_condition_with_completion_token (DDSCondition *condition, DDSAsyncWaitSetCompletionToken *completion_token)
 Detaches the specified DDSCondition from this DDSAsyncWaitSet. More...
 
virtual DDS_ReturnCode_t unlock_condition (DDSCondition *condition)
 Allows the DDSCondition under dispatch to be available for concurrent dispatch from another thread from the pool. More...
 
virtual DDS_ReturnCode_t get_property (DDS_AsyncWaitSetProperty_t &property)
 Retrieves the DDS_AsyncWaitSetProperty_t configuration of the associated DDSAsyncWaitSet. More...
 
virtual DDS_ReturnCode_t get_conditions (DDSConditionSeq &attached_conditions)
 Retrieves the list of attached DDSCondition (s). More...
 
virtual DDSAsyncWaitSetCompletionTokencreate_completion_token ()
 Creates a new DDSAsyncWaitSetCompletionToken. More...
 
virtual DDS_ReturnCode_t delete_completion_token (DDSAsyncWaitSetCompletionToken *completion_token)
 Deletes a DDSAsyncWaitSetCompletionToken previously created from this DDSAsyncWaitSet. More...
 
 DDSAsyncWaitSet ()
 Creates a DDSAsyncWaitSet with default property. More...
 
 DDSAsyncWaitSet (const DDS_AsyncWaitSetProperty_t &property)
 Single-argument constructor that allows creating a a DDSAsyncWaitSet with custom behavior. More...
 
 DDSAsyncWaitSet (const DDS_AsyncWaitSetProperty_t &property, DDSAsyncWaitSetListener *listener)
 Constructor that allows specifying a DDSAsyncWaitSetListener. More...
 
 DDSAsyncWaitSet (const DDS_AsyncWaitSetProperty_t &property, DDSAsyncWaitSetListener *listener, DDSThreadFactory *thread_factory)
 Constructor with arguments that allow specifying behavior different than the default one, including specifying a DDSThreadFactory for the creation and deletion of the threads within the thread pool. More...
 
virtual ~DDSAsyncWaitSet ()
 Deletes a DDSAsyncWaitSet. More...
 

Static Public Attributes

static DDSAsyncWaitSetCompletionToken *const COMPLETION_TOKEN_USE_IMPLICIT_AND_WAIT
 For the operations that allow an DDSAsyncWaitSetCompletionToken, this sentinel can be provided to indicate an DDSAsyncWaitSet to use the implicit completion token and wait on it for request completion. More...
 
static DDSAsyncWaitSetCompletionToken *const COMPLETION_TOKEN_IGNORE
 For the operations that allow an DDSAsyncWaitSetCompletionToken, this sentinel can be provided to indicate an DDSAsyncWaitSet to perform the action associating a 'null' completion token. More...
 

Detailed Description

A class for dispatching DDSCondition objects using separate threads of execution. You can see this class as an extension of a DDSWaitSet that allows asynchronously waiting for the attached DDSCondition objects to trigger and provide a notification by calling DDSCondition::dispatch.

DDSAsyncWaitSet provides a proactive model to process application events through DDSCondition objects. DDSAsyncWaitSet owns a pool of threads to asynchronously wait for the attached DDSCondition objects to trigger and dispatch them upon wakeup. The asynchronous behavior is the main key different with regards to the DDSWaitSet.

The class diagram and its collaborators is shown below:

DDSAsyncWaitSet.png
::DDSAsyncWaitSet

AsyncWaitSet Thread Orchestration

DDSAsyncWaitSet internally applies a leader-follower pattern for the orchestration of the thread pool. Once a DDSAsyncWaitSet 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:

  • The Leader thread is the one waiting for the attached DDSCondition to trigger. Remaining threads in the pool, if any, are either idle awaiting to become the leader or busy while processing active DDSCondition.
  • Upon wait wakeup, the Leader thread resigns its leader status to become a Processor thread and dispatch the next active DDSCondition through the DDSCondition::dispatch operation.
  • One of the Follower threads wakes up and becomes the new leader to resume the wait for DDSCondition.
DDSAsyncWaitSet_leader-follower.png
Thread orchestration in a ::DDSAsyncWaitSet

This behavior implies the following considerations:

  • Only one thread a time can wait for the attached DDSCondition objects to trigger. From a pool of M threads, only one is the leader, P are processing active DDSCondition, and F are idle followers.
  • A thread can dispatch only one active DDSCondition at a time.
  • DDSAsyncWaitSet efficiently distributes threads to dispatch DDSCondition objects on demand. This avoids underutilizing a thread if DDSCondition objects do not trigger or trigger unfrequently.
  • At a given time, all the threads in the pool could be in processing state. In this situation, the DDSAsyncWaitSet is not able to wait for more DDSCondition objects until one thread becomes the leader.

DDSAsyncWaitSet has a built-in dispatcher that guarantees fairness and avoids starvation of DDSCondition objects. By applying a round-robin distribution policy, each attached and active DDSCondition is dispatched within a finite period of time, assuming the DDSConditionHandler always return control after the DDSCondition::dispatch operation.

AsyncWaitSet Thread Safety

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

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

For instance to detach a DDSCondition, the DDSAsyncWaitSet 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 DDSAsyncWaitSet is started. Otherwise the internal request will be directly executed by the calling thread.

For a finer control on this behavior, each DDSAsyncWaitSet operation where this applies comes in two flavors:

  • Default: the operation hides all the details of the completion token and returns after the operation completes. Operations of this kind internally use an implicit DDSAsyncWaitSetCompletionToken. The DDSAsyncWaitSet creates and reuses DDSAsyncWaitSetCompletionToken objects as needed. This is the recommended flavor unless your application has special resource needs.
  • With completion token: An overloaded version of the default one that also receives an DDSAsyncWaitSetCompletionToken object on which you can wait on at any time for the actual operation to complete. This flavor is available to assist applications with resource constraints and that want more control on the interaction with the thread pool of the DDSAsyncWaitSet.

Condition Locking

DDSAsyncWaitSet incorporates a safety mechanism that prevents calling DDSCondition::dispatch concurrently. DDSAsyncWaitSet locks the DDSCondition 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 DDSCondition 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 DDSAsyncWaitSet 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. DDSAsyncWaitSet will still allows you to unlock a DDSCondition so any other available thread can dispatch the same condition concurrently while preventing the above mentioned problems. You can achive this by calling DDSAsyncWaitSet::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 DDSCondition processing, you can listen to other kind of internal events related to the DDSAsyncWaitSet and its thread pool by means of the DDSAsyncWaitSetListener.

DDSAsyncWaitSet exposes operations to start and stop the asynchronous wait, which involves the creation and deletion of the thread pool respectively.

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

MT Safety:
Safe.
See also
DDSWaitSet
DDSCondition
DDSAsyncWaitSetListener
DDSAsyncWaitSetCompletionToken.
DDS_AsyncWaitSetProperty_t

Constructor & Destructor Documentation

◆ DDSAsyncWaitSet() [1/4]

DDSAsyncWaitSet::DDSAsyncWaitSet ( )

Creates a DDSAsyncWaitSet with default property.

◆ DDSAsyncWaitSet() [2/4]

DDSAsyncWaitSet::DDSAsyncWaitSet ( const DDS_AsyncWaitSetProperty_t property)

Single-argument constructor that allows creating a a DDSAsyncWaitSet with custom behavior.

You can provide DDS_ASYNC_WAITSET_PROPERTY_DEFAULT as property to create an DDSAsyncWaitSet with default behavior.

The DDSAsyncWaitSet is created with no listener installed.

Parameters
property<<in>> configuration DDS_AsyncWaitSetProperty_t
Returns
A new DDSAsyncWaitSet or NULL if one could not be allocated.

◆ DDSAsyncWaitSet() [3/4]

DDSAsyncWaitSet::DDSAsyncWaitSet ( const DDS_AsyncWaitSetProperty_t property,
DDSAsyncWaitSetListener listener 
)

Constructor that allows specifying a DDSAsyncWaitSetListener.

Creates a new DDSAsyncWaitSet with the specified property DDS_AsyncWaitSetProperty_t and DDSAsyncWaitSetListener.

Parameters
property<<in>> configuration DDS_AsyncWaitSetProperty_t
listener<<in>> the DDSAsyncWaitSetListener. Cannot be NULL.
Returns
A new DDSAsyncWaitSet or NULL if one could not be allocated.

◆ DDSAsyncWaitSet() [4/4]

DDSAsyncWaitSet::DDSAsyncWaitSet ( const DDS_AsyncWaitSetProperty_t property,
DDSAsyncWaitSetListener listener,
DDSThreadFactory thread_factory 
)

Constructor with arguments that allow specifying behavior different than the default one, including specifying a DDSThreadFactory for the creation and deletion of the threads within the thread pool.

This operation extends DDSAsyncWaitSet::DDSAsyncWaitSet() by allowing to provide a DDSThreadFactory

Parameters
property<<in>> configuration DDS_AsyncWaitSetProperty_t
listener<<in>> the DDSAsyncWaitSetListener. Cannot be NULL.
thread_factory<<in>> DDSThreadFactory for the creation and deletion of threads.
Returns
A new DDSAsyncWaitSet or NULL if one could not be allocated.

◆ ~DDSAsyncWaitSet()

virtual DDSAsyncWaitSet::~DDSAsyncWaitSet ( )
virtual

Deletes a DDSAsyncWaitSet.

If the DDSAsyncWaitSet is started, this operation will initiate the stop procedure and block until it completes.

The deletion will fail if there are outstanding DDSAsyncWaitSetCompletionToken that have not been deleted.

Any outstanding DDSAsyncWaitSet must be deleted before finalizing the DDSDomainParticipantFactory. Otherwise undefined behavior may occur.

See also
DDSAsyncWaitSet::DDSAsyncWaitSet()

Member Function Documentation

◆ start()

virtual DDS_ReturnCode_t DDSAsyncWaitSet::start ( )
virtual

Initiates the asynchronous wait on this DDSAsyncWaitSet.

This operation is equivalent to calling DDSAsyncWaitSet::start_with_completion_token providing DDSAsyncWaitSet::COMPLETION_TOKEN_USE_IMPLICIT_AND_WAIT as a completion_token.

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

Returns
One of the Standard Return Codes
See also
DDSAsyncWaitSet::start_with_completion_token
DDSAsyncWaitSet::stop

◆ start_with_completion_token()

virtual DDS_ReturnCode_t DDSAsyncWaitSet::start_with_completion_token ( DDSAsyncWaitSetCompletionToken completion_token)
virtual

Initiates the asynchronous wait on this DDSAsyncWaitSet.

If this operation succeeds, a start request has been scheduled and your application can use the provided completion_token to wait for this DDSAsyncWaitSet to process the request. If the DDSAsyncWaitSetCompletionToken::wait operation returns successfully, it is guranteed that the thread pool has been created and the leader thread is waiting for the attached DDSCondition to trigger.

Once this DDSAsyncWaitSet is started, attached DDSCondition will be dispatched through the DDSCondition::dispatch operation when they trigger.

The start procedure causes the DDSAsyncWaitSet 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 DDSAsyncWaitSetListener is installed, this DDSAsyncWaitSet will sequentially invoke the DDSAsyncWaitSetListener::on_thread_spawned once per spwaned thread.

A DDSAsyncWaitSet can be restarted after a stop. If this DDSAsyncWaitSet 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 DDSAsyncWaitSetCompletionToken instance that can be used by your application to wait for the start request to complete. You can provide one of the special sentinels DDSAsyncWaitSet::COMPLETION_TOKEN_USE_IMPLICIT_AND_WAIT and DDSAsyncWaitSet::COMPLETION_TOKEN_IGNORE.
Returns
One of the Standard Return Codes
See also
DDSAsyncWaitSet::start
DDSAsyncWaitSet::stop_with_completion_token
DDSWaitSet::wait

◆ stop()

virtual DDS_ReturnCode_t DDSAsyncWaitSet::stop ( )
virtual

Initiates the stop procedure on this DDSAsyncWaitSet that will stop the asynchronous wait.

This operation is equivalent to calling DDSAsyncWaitSet::stop_with_completion_token providing DDSAsyncWaitSet::COMPLETION_TOKEN_USE_IMPLICIT_AND_WAIT as a completion_token.

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

Returns
One of the Standard Return Codes
See also
DDSAsyncWaitSet::start_with_completion_token
DDSAsyncWaitSet::stop

◆ stop_with_completion_token()

virtual DDS_ReturnCode_t DDSAsyncWaitSet::stop_with_completion_token ( DDSAsyncWaitSetCompletionToken completion_token)
virtual

Initiates the stop procedure on this DDSAsyncWaitSet 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 DDSAsyncWaitSet to process the request. If the DDSAsyncWaitSetCompletionToken::wait operation returns successfully, it is guranteed that the thread pool has been deleted and this DDSAsyncWaitSet no longer process any of the attached DDSCondition objects.

Once this DDSAsyncWaitSet is stopped, the DDSCondition::dispatch will no longer be called on any of the attached DDSCondition, no matter what their trigger value is.

The stop procedure causes the DDSAsyncWaitSet 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 DDSAsyncWaitSetListener is installed, this DDSAsyncWaitSet will sequentially invoke the DDSAsyncWaitSetListener::on_thread_deleted once per deleted thread.

If this DDSAsyncWaitSet 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 DDSAsyncWaitSetCompletionToken instance that can be used by your application to wait for the stop request to complete. You can provide one of the special sentinels DDSAsyncWaitSet::COMPLETION_TOKEN_USE_IMPLICIT_AND_WAIT and DDSAsyncWaitSet::COMPLETION_TOKEN_IGNORE.
Returns
One of the Standard Return Codes
See also
DDSAsyncWaitSet::stop
DDSAsyncWaitSet::start_with_completion_token

◆ attach_condition()

virtual DDS_ReturnCode_t DDSAsyncWaitSet::attach_condition ( DDSCondition condition)
virtual

Attaches the specified DDSCondition to this DDSAsyncWaitSet.

This operation is equivalent to calling DDSAsyncWaitSet::attach_condition_with_completion_token providing DDSAsyncWaitSet::COMPLETION_TOKEN_USE_IMPLICIT_AND_WAIT as a completion_token.

This operation will block until the attach request completes. Upon successful return, it is guaranteed that the specified DDSCondition is attached.

Parameters
condition<<in>> DDSCondition to be attached.
Returns
One of the Standard Return Codes
See also
DDSAsyncWaitSet::attach_condition_with_completion_token

◆ detach_condition()

virtual DDS_ReturnCode_t DDSAsyncWaitSet::detach_condition ( DDSCondition condition)
virtual

Deaches the specified DDSCondition from this DDSAsyncWaitSet.

This operation is equivalent to call DDSAsyncWaitSet::detach_condition_with_completion_token providing DDSAsyncWaitSet::COMPLETION_TOKEN_USE_IMPLICIT_AND_WAIT as a completion_token.

This operation blocks until the detach request completes. Upon successful return, it is guaranteed that the specified DDSCondition is detached.

Parameters
condition<<in>> DDSCondition to be detached.
Returns
One of the Standard Return Codes
See also
DDSAsyncWaitSet::detach_condition_with_completion_token

◆ attach_condition_with_completion_token()

virtual DDS_ReturnCode_t DDSAsyncWaitSet::attach_condition_with_completion_token ( DDSCondition condition,
DDSAsyncWaitSetCompletionToken completion_token 
)
virtual

Attaches the specified DDSCondition to this DDSAsyncWaitSet.

If this operation succeeds, an attach request has been scheduled and your application can use the output parameter completion_token to wait for this DDSAsyncWaitSet to process the request. DDSAsyncWaitSetCompletionToken::wait operation returns successfully, it is guaranteed that the DDSCondition is attached to this DDSAsyncWaitSet.

Once the DDSCondition is attached, its trigger value may cause the leader thread of the DDSAsyncWaitSet to wake up call the DDSCondition::dispatch operation.

DDSCondition may be attached at any time independently of the state of the DDSAsyncWaitSet.

Parameters
condition<<in>> DDSCondition to be attached.
completion_token<<inout>> a valid DDSAsyncWaitSetCompletionToken instance that can be used by your application to wait for the attach request to complete. You can provide one of the special sentinels DDSAsyncWaitSet::COMPLETION_TOKEN_USE_IMPLICIT_AND_WAIT and DDSAsyncWaitSet::COMPLETION_TOKEN_IGNORE.
Returns
One of the Standard Return Codes
See also
DDSAsyncWaitSet::attach_condition
DDSAsyncWaitSet::detach_condition_with_completion_token
DDSAsyncWaitSetCompletionToken::wait

◆ detach_condition_with_completion_token()

virtual DDS_ReturnCode_t DDSAsyncWaitSet::detach_condition_with_completion_token ( DDSCondition condition,
DDSAsyncWaitSetCompletionToken completion_token 
)
virtual

Detaches the specified DDSCondition from this DDSAsyncWaitSet.

If this operation succeeds, a detach request has been scheduled and your application can use the provided completion_token to wait for this DDSAsyncWaitSet to process the request. If the DDSAsyncWaitSetCompletionToken::wait operation returns successfully, it is guaranteed that the DDSCondition is detached from this DDSAsyncWaitSet.

Once the DDSCondition is detached, it is guaranteed that the DDSAsyncWaitSet will no longer process it so it is safe for your application to release any resources associated with the detached DDSCondition.

DDSCondition may be detached at any time independently of the state of the DDSAsyncWaitSet.

Parameters
condition<<in>> DDSCondition to be detached.
completion_token<<inout>> a valid DDSAsyncWaitSetCompletionToken instance that can be used by your application to wait for the detach request to complete. You can provide one of the special sentinels DDSAsyncWaitSet::COMPLETION_TOKEN_USE_IMPLICIT_AND_WAIT and DDSAsyncWaitSet::COMPLETION_TOKEN_IGNORE.
Returns
One of the Standard Return Codes
See also
DDSAsyncWaitSet::detach_condition
DDSAsyncWaitSet::attach_condition_with_completion_token
DDSAsyncWaitSetCompletionToken::wait

◆ unlock_condition()

virtual DDS_ReturnCode_t DDSAsyncWaitSet::unlock_condition ( DDSCondition condition)
virtual

Allows the DDSCondition 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 DDSCondition this DDSAsyncWaitSet is dispatching. After succesfully calling this operation, if the DDSCondition becomes active this DDSAsyncWaitSet is allowed to dispatch it again from any available thread from the pool.

You may call this operation any time you need the same DDSCondition to be dispatched concurrently.

This operation will fail with DDS_RETCODE_PRECONDITION_NOT_MET if you call it from a different context than the dispatch callback or on a different DDSCondition.

Returns
One of the Standard Return Codes

◆ get_property()

virtual DDS_ReturnCode_t DDSAsyncWaitSet::get_property ( DDS_AsyncWaitSetProperty_t property)
virtual

Retrieves the DDS_AsyncWaitSetProperty_t configuration of the associated DDSAsyncWaitSet.

Parameters
property<<out>>
Returns
One of the Standard Return Codes

◆ get_conditions()

virtual DDS_ReturnCode_t DDSAsyncWaitSet::get_conditions ( DDSConditionSeq attached_conditions)
virtual

Retrieves the list of attached DDSCondition (s).

Parameters
attached_conditions<<inout>> a DDSConditionSeq object where the list of attached conditions will be returned.
Returns
One of the Standard Return Codes
See also
DDSAsyncWaitSet::attach_condition
DDSAsyncWaitSet::detach_condition

◆ create_completion_token()

virtual DDSAsyncWaitSetCompletionToken* DDSAsyncWaitSet::create_completion_token ( )
virtual

◆ delete_completion_token()

virtual DDS_ReturnCode_t DDSAsyncWaitSet::delete_completion_token ( DDSAsyncWaitSetCompletionToken completion_token)
virtual

Deletes a DDSAsyncWaitSetCompletionToken previously created from this DDSAsyncWaitSet.

This operation will fail the if the specified completion_token was not created from this DDSAsyncWaitSet.

This operation will fail if the specified completion_token is associated with a request that has not completed yet.

Parameters
completion_token<<inout>> a valid DDSAsyncWaitSetCompletionToken created from this DDSAsyncWaitSet.
Returns
One of the Standard Return Codes
See also
DDSAsyncWaitSet::create_completion_token
DDSAsyncWaitSet::~DDSAsyncWaitSet()