RTI Connext Traditional C++ API  Version 6.0.1
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
DDSWaitSet Class Reference

<<interface>> Allows an application to wait until one or more of the attached DDSCondition objects has a trigger_value of DDS_BOOLEAN_TRUE or else until the timeout expires. More...

Public Member Functions

virtual DDS_ReturnCode_t wait (DDSConditionSeq &active_conditions, const DDS_Duration_t &timeout)
 Allows an application thread to wait for the occurrence of certain conditions.
 
virtual DDS_ReturnCode_t attach_condition (DDSCondition *cond)
 Attaches a DDSCondition to the DDSWaitSet.
 
virtual DDS_ReturnCode_t detach_condition (DDSCondition *cond)
 Detaches a DDSCondition from the DDSWaitSet.
 
virtual DDS_ReturnCode_t get_conditions (DDSConditionSeq &attached_conditions)
 Retrieves the list of attached DDSCondition (s).
 
virtual DDS_ReturnCode_t set_property (const DDS_WaitSetProperty_t &prop)
 <<extension>> Sets the DDS_WaitSetProperty_t, to configure the associated DDSWaitSet to return after one or more trigger events have occurred.
 
virtual DDS_ReturnCode_t get_property (DDS_WaitSetProperty_t &prop)
 <<extension>> Retrieves the DDS_WaitSetProperty_t configuration of the associated DDSWaitSet.
 
virtual ~DDSWaitSet ()
 Destructor.
 
 DDSWaitSet ()
 Default no-argument constructor.
 
 DDSWaitSet (const DDS_WaitSetProperty_t &prop)
 <<extension>> Constructor for a DDSWaitSet that may delay for more while specifying that will be woken up after the given number of events or delay period, whichever happens first
 

Detailed Description

<<interface>> Allows an application to wait until one or more of the attached DDSCondition objects has a trigger_value of DDS_BOOLEAN_TRUE or else until the timeout expires.

Usage

DDSCondition (s) (in conjunction with wait-sets) provide an alternative mechanism to allow the middleware to communicate communication status changes (including arrival of data) to the application.

DDSWaitSetConditions.png
::DDSWaitSet and ::DDSCondition (s)

This mechanism is wait-based. Its general use pattern is as follows:

Usually the first step is done in an initialization phase, while the others are put in the application main loop.

As there is no extra information passed from the middleware to the application when a wait returns (only the list of triggered DDSCondition objects), DDSCondition objects are meant to embed all that is needed to react properly when enabled. In particular, DDSEntity-related conditions are related to exactly one DDSEntity and cannot be shared.

The blocking behavior of the DDSWaitSet is illustrated below.

DDSWaitSetBlocking.png
::DDSWaitSet blocking behavior

The result of a DDSWaitSet::wait operation depends on the state of the DDSWaitSet, which in turn depends on whether at least one attached DDSCondition has a trigger_value of DDS_BOOLEAN_TRUE. If the wait operation is called on DDSWaitSet with state BLOCKED, it will block the calling thread. If wait is called on a DDSWaitSet with state UNBLOCKED, it will return immediately. In addition, when the DDSWaitSet transitions from BLOCKED to UNBLOCKED it wakes up any threads that had called wait on it.

A key aspect of the Condition and WaitSet mechanism is the setting of the trigger_value of each DDSCondition.

Trigger State of a ::DDSStatusCondition

The trigger_value of a DDSStatusCondition is the boolean OR of the ChangedStatusFlag of all the communication statuses (see Status Kinds) to which it is sensitive. That is, trigger_value == DDS_BOOLEAN_FALSE only if all the values of the ChangedStatusFlags are DDS_BOOLEAN_FALSE.

The sensitivity of the DDSStatusCondition to a particular communication status is controlled by the list of enabled_statuses set on the condition by means of the DDSStatusCondition::set_enabled_statuses operation.

Once the trigger_value of a StatusCondition becomes true, it remains true until the status that changed is reset. To reset a status, call the related get_*_status() operation. Or, in the case of the data available status, call read(), take(), or one of their variants. Therefore, if you are using a DDSStatusCondition on a DDSWaitSet to be notified of events, your thread will wake up when one of the statuses associated with the StatusCondition becomes true. If you do not reset the status, the StatusCondition trigger_value remains true and your WaitSet will not block again; it will immediately wake up when you call DDSWaitSet::wait.

Trigger State of a ::DDSReadCondition

Similar to the DDSStatusCondition, a DDSReadCondition also has a trigger_value that determines whether the attached DDSWaitSet is BLOCKED or UNBLOCKED. However, unlike the DDSStatusCondition, the trigger_value of the DDSReadCondition is tied to the presence of at least a sample managed by RTI Connext with DDS_SampleStateKind and DDS_ViewStateKind matching those of the DDSReadCondition. Furthermore, for the DDSQueryCondition to have a trigger_value == DDS_BOOLEAN_TRUE, the data associated with the sample must be such that the query_expression evaluates to DDS_BOOLEAN_TRUE.

The fact that the trigger_value of a DDSReadCondition depends on the presence of samples on the associated DDSDataReader implies that a single take operation can potentially change the trigger_value of several DDSReadCondition or DDSQueryCondition conditions. For example, if all samples are taken, any DDSReadCondition and DDSQueryCondition conditions associated with the DDSDataReader that had their trigger_value==TRUE before will see the trigger_value change to FALSE. Note that this does not guarantee that DDSWaitSet objects that were separately attached to those conditions will not be woken up. Once we have trigger_value==TRUE on a condition, it may wake up the attached DDSWaitSet, the condition transitioning to trigger_value==FALSE does not necessarily 'unwakeup' the WaitSet as 'unwakening' may not be possible in general.

The consequence is that an application blocked on a DDSWaitSet may return from the wait with a list of conditions, some of which are not no longer 'active'. This is unavoidable if multiple threads are concurrently waiting on separate DDSWaitSet objects and taking data associated with the same DDSDataReader entity.

To elaborate further, consider the following example: A DDSReadCondition that has a sample_state_mask = {DDS_NOT_READ_SAMPLE_STATE} will have trigger_value of DDS_BOOLEAN_TRUE whenever a new sample arrives and will transition to DDS_BOOLEAN_FALSE as soon as all the newly-arrived samples are either read (so their sample state changes to READ) or taken (so they are no longer managed by RTI Connext). However if the same DDSReadCondition had a sample_state_mask = { DDS_READ_SAMPLE_STATE, DDS_NOT_READ_SAMPLE_STATE }, then the trigger_value would only become DDS_BOOLEAN_FALSE once all the newly-arrived samples are taken (it is not sufficient to read them as that would only change the sample state to READ), which overlaps the mask on the DDSReadCondition.

Trigger State of a ::DDSGuardCondition

The trigger_value of a DDSGuardCondition is completely controlled by the application via the operation DDSGuardCondition::set_trigger_value.

See Also
Status Kinds
DDSStatusCondition, DDSGuardCondition
DDSListener

Constructor & Destructor Documentation

virtual DDSWaitSet::~DDSWaitSet ( )
virtual

Destructor.

Releases the resources asociated with this DDSWaitSet.

Freeing a null pointer is safe and does nothing.

MT Safety:
UNSAFE. It is not safe to delete a DDSWaitSet while another thread is calling an API that uses the entity. For instance, a thread must not delete a WaitSet while another thread is blocked with DDSWaitSet::wait. To properly handle this scenario, you can use a DDSGuardCondition to wake up the WaitSet and then wait for the finalization of the thread.
DDSWaitSet::DDSWaitSet ( )

Default no-argument constructor.

Construct a new DDSWaitSet.

Returns
A new DDSWaitSet or NULL if one could not be allocated.
DDSWaitSet::DDSWaitSet ( const DDS_WaitSetProperty_t prop)

<<extension>> Constructor for a DDSWaitSet that may delay for more while specifying that will be woken up after the given number of events or delay period, whichever happens first

Constructs a new DDSWaitSet.

Returns
A new DDSWaitSet or NULL if one could not be allocated.

Member Function Documentation

virtual DDS_ReturnCode_t DDSWaitSet::wait ( DDSConditionSeq active_conditions,
const DDS_Duration_t timeout 
)
virtual

Allows an application thread to wait for the occurrence of certain conditions.

If none of the conditions attached to the DDSWaitSet have a trigger_value of DDS_BOOLEAN_TRUE, the wait operation will block, suspending the calling thread.

The result of the wait operation is the list of all the attached conditions that have a trigger_value of DDS_BOOLEAN_TRUE (i.e., the conditions that unblocked the wait).

Note: The resolution of the timeout period is constrained by the resolution of the system clock.

The wait operation takes a timeout argument that specifies the maximum duration for the wait. If this duration is exceeded and none of the attached DDSCondition objects are DDS_BOOLEAN_TRUE, wait will return with the return code DDS_RETCODE_TIMEOUT. In this case, the resulting list of conditions will be empty.

Note: The resolution of the timeout period is constrained by the resolution of the system clock.

DDS_RETCODE_TIMEOUT will not be returned when the timeout duration is exceeded if attached DDSCondition objects are DDS_BOOLEAN_TRUE, or in the case of a DDSWaitSet waiting for more than one trigger event, if one or more trigger events have occurred.

It is not allowable for more than one application thread to be waiting on the same DDSWaitSet. If the wait operation is invoked on a DDSWaitSet that already has a thread blocking on it, the operation will return immediately with the value DDS_RETCODE_PRECONDITION_NOT_MET.

Parameters
active_conditions<<inout>> a valid non-NULL DDSConditionSeq object. Note that RTI Connext will not allocate a new object if active_conditions is NULL; the method will return DDS_RETCODE_PRECONDITION_NOT_MET.
timeout<<in>> a wait timeout
Returns
One of the Standard Return Codes or DDS_RETCODE_PRECONDITION_NOT_MET or DDS_RETCODE_TIMEOUT.
virtual DDS_ReturnCode_t DDSWaitSet::attach_condition ( DDSCondition cond)
virtual

Attaches a DDSCondition to the DDSWaitSet.

It is possible to attach a DDSCondition on a DDSWaitSet that is currently being waited upon (via the wait operation). In this case, if the DDSCondition has a trigger_value of DDS_BOOLEAN_TRUE, then attaching the condition will unblock the DDSWaitSet.

Parameters
cond<<in>> Condition to be attached.
Returns
One of the Standard Return Codes, or DDS_RETCODE_OUT_OF_RESOURCES.
virtual DDS_ReturnCode_t DDSWaitSet::detach_condition ( DDSCondition cond)
virtual

Detaches a DDSCondition from the DDSWaitSet.

If the DDSCondition was not attached to the DDSWaitSet the operation will return DDS_RETCODE_BAD_PARAMETER.

Parameters
cond<<in>> Condition to be detached.
Returns
One of the Standard Return Codes, or DDS_RETCODE_PRECONDITION_NOT_MET.
virtual DDS_ReturnCode_t DDSWaitSet::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, or DDS_RETCODE_OUT_OF_RESOURCES.
virtual DDS_ReturnCode_t DDSWaitSet::set_property ( const DDS_WaitSetProperty_t prop)
virtual

<<extension>> Sets the DDS_WaitSetProperty_t, to configure the associated DDSWaitSet to return after one or more trigger events have occurred.

Parameters
prop<<in>>
Returns
One of the Standard Return Codes
virtual DDS_ReturnCode_t DDSWaitSet::get_property ( DDS_WaitSetProperty_t prop)
virtual

<<extension>> Retrieves the DDS_WaitSetProperty_t configuration of the associated DDSWaitSet.

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

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