RTI Connext C API Version 7.4.0
|
DDS_Condition and DDS_WaitSet and related items. More...
Modules | |
AsyncWaitSet | |
<<extension>> A specialization of DDS_WaitSet that provides a mechanism to perform the wait asynchronously and uses a thread pool to dispatch the attached active DDS_Condition. | |
Data Structures | |
struct | DDS_ConditionSeq |
Instantiates FooSeq < DDS_Condition > More... | |
struct | DDS_ConditionHandler |
<<extension>> <<interface>> Handler called by the DDS_Condition_dispatch. More... | |
struct | DDS_WaitSetProperty_t |
<<extension>> Specifies the DDS_WaitSet behavior for multiple trigger events. More... | |
Macros | |
#define | DDS_ConditionHandler_INITIALIZER |
<<experimental>> <<extension>> Initializer for new DDS_ConditionHandler. More... | |
#define | DDS_WaitSetProperty_t_INITIALIZER |
<<extension>> Initializer for new property instances. More... | |
Typedefs | |
typedef struct DDS_ConditionImpl | DDS_Condition |
<<interface>> Root class for all the conditions that may be attached to a DDS_WaitSet. More... | |
typedef void(* | DDS_ConditionHandler_OnConditionTriggeredCallback) (void *handler_data, DDS_Condition *condition) |
Prototype of a DDS_ConditionHandler on_condition_triggered function. More... | |
typedef struct DDS_GuardConditionImpl | DDS_GuardCondition |
<<interface>> A specific DDS_Condition whose trigger_value is completely under the control of the application. More... | |
typedef struct DDS_StatusConditionImpl | DDS_StatusCondition |
<<interface>> A specific DDS_Condition that is associated with each DDS_Entity. More... | |
typedef struct DDS_WaitSetImpl | DDS_WaitSet |
<<interface>> Allows an application to wait until one or more of the attached DDS_Condition objects has a trigger_value of DDS_BOOLEAN_TRUE or else until the timeout expires. More... | |
DDS_Condition and DDS_WaitSet and related items.
#define DDS_ConditionHandler_INITIALIZER |
<<experimental>> <<extension>> Initializer for new DDS_ConditionHandler.
No memory is allocated. New DDS_ConditionHandler instances stored in the stack should be initialized with this value before they are passed to any functions.
#define DDS_WaitSetProperty_t_INITIALIZER |
<<extension>> Initializer for new property instances.
Default property specifies max_event_count
= 1 and max_event_delay
= DDS_DURATION_INFINITE
typedef struct DDS_ConditionImpl DDS_Condition |
<<interface>> Root class for all the conditions that may be attached to a DDS_WaitSet.
This basic class is specialised in three classes:
DDS_GuardCondition, DDS_StatusCondition, and DDS_ReadCondition.
A DDS_Condition has a trigger_value
that can be DDS_BOOLEAN_TRUE or DDS_BOOLEAN_FALSE and is set automatically by RTI Connext.
typedef void(* DDS_ConditionHandler_OnConditionTriggeredCallback) (void *handler_data, DDS_Condition *condition) |
Prototype of a DDS_ConditionHandler on_condition_triggered function.
handler_data | <<in>> Data associated with the handler when the handler is set. |
condition | st_in associated DDS_Condition on which the DDS_Condition_dispatch is called. |
typedef struct DDS_GuardConditionImpl DDS_GuardCondition |
<<interface>> A specific DDS_Condition whose trigger_value
is completely under the control of the application.
The DDS_GuardCondition provides a way for an application to manually wake up a DDS_WaitSet. This is accomplished by attaching the DDS_GuardCondition to the DDS_WaitSet and then setting the trigger_value
by means of the DDS_GuardCondition_set_trigger_value operation.
typedef struct DDS_StatusConditionImpl DDS_StatusCondition |
<<interface>> A specific DDS_Condition that is associated with each DDS_Entity.
The trigger_value
of the DDS_StatusCondition depends on the communication status of that entity (e.g., arrival of data, loss of information, etc.), 'filtered' by the set of enabled_statuses
on the DDS_StatusCondition.
typedef struct DDS_WaitSetImpl DDS_WaitSet |
<<interface>> Allows an application to wait until one or more of the attached DDS_Condition objects has a trigger_value
of DDS_BOOLEAN_TRUE or else until the timeout expires.
DDS_Condition (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.
"::DDS_WaitSet and ::DDS_Condition (s)"
This mechanism is wait-based. Its general use pattern is as follows:
trigger_value
of one or several DDS_Condition objects become DDS_BOOLEAN_TRUE.
active_conditions, the list of DDS_Condition objects with trigger_value
== DDS_BOOLEAN_TRUE) to actually get the information: by calling DDS_Entity_get_status_changes and then get_<communication_status>
() on the relevant DDS_Entity, if the condition is a DDS_StatusCondition and the status changes, refer to plain communication status;
by calling DDS_Entity_get_status_changes and then DDS_Subscriber_get_datareaders on the relevant DDS_Subscriber (and then FooDataReader_read() or FooDataReader_take on the returned DDS_DataReader objects), if the condition is a DDS_StatusCondition and the status changes refers to DDS_DATA_ON_READERS_STATUS;
by calling DDS_Entity_get_status_changes and then FooDataReader_read() or FooDataReader_take on the relevant DDS_DataReader, if the condition is a DDS_StatusCondition and the status changes refers to DDS_DATA_AVAILABLE_STATUS;
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 DDS_Condition objects), DDS_Condition objects are meant to embed all that is needed to react properly when enabled. In particular, DDS_Entity-related conditions are related to exactly one DDS_Entity and cannot be shared.
The blocking behavior of the DDS_WaitSet is illustrated below.
blocking behavior"
The result of a DDS_WaitSet_wait operation depends on the state of the DDS_WaitSet, which in turn depends on whether at least one attached DDS_Condition has a trigger_value
of DDS_BOOLEAN_TRUE. If the wait operation is called on DDS_WaitSet with state BLOCKED, it will block the calling thread. If wait is called on a DDS_WaitSet with state UNBLOCKED, it will return immediately. In addition, when the DDS_WaitSet 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 DDS_Condition.
The DDS_WaitSet cannot be used after calling DDS_DomainParticipantFactory_finalize_instance.
The trigger_value
of a DDS_StatusCondition 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 DDS_StatusCondition to a particular communication status is controlled by the list of enabled_statuses
set on the condition by means of the DDS_StatusCondition_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 DDS_StatusCondition on a DDS_WaitSet 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 DDS_WaitSet_wait.
Similar to the DDS_StatusCondition, a DDS_ReadCondition also has a trigger_value
that determines whether the attached DDS_WaitSet is BLOCKED or UNBLOCKED. However, unlike the DDS_StatusCondition, the trigger_value
of the DDS_ReadCondition is tied to the presence of at least a sample managed by RTI Connext with DDS_SampleStateKind and DDS_ViewStateKind matching those of the DDS_ReadCondition. Furthermore, for the DDS_QueryCondition 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 DDS_ReadCondition depends on the presence of samples on the associated DDS_DataReader implies that a single take operation can potentially change the trigger_value
of several DDS_ReadCondition or DDS_QueryCondition conditions. For example, if all samples are taken, any DDS_ReadCondition and DDS_QueryCondition conditions associated with the DDS_DataReader that had their trigger_value==TRUE
before will see the trigger_value
change to FALSE. Note that this does not guarantee that DDS_WaitSet 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 DDS_WaitSet, 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 DDS_WaitSet 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 DDS_WaitSet objects and taking data associated with the same DDS_DataReader entity.
To elaborate further, consider the following example: A DDS_ReadCondition 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 DDS_ReadCondition 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 DDS_ReadCondition.
The trigger_value
of a DDS_GuardCondition is completely controlled by the application via the operation DDS_GuardCondition_set_trigger_value.
DDS_Boolean DDS_Condition_get_trigger_value | ( | DDS_Condition * | self | ) |
DDS_ReturnCode_t DDS_Condition_set_handler | ( | DDS_Condition * | self, |
const struct DDS_ConditionHandler * | handler | ||
) |
<<extension>> Registers a DDS_ConditionHandler in this DDS_Condition.
This operation replaces any existing registered handler. If there is any resources associated with an existing registered handler that need to be released, you may first call DDS_Condition_get_handler to retrieve the handler.
self | <<in>> Cannot be NULL. |
handler | The DDS_ConditionHandler to be called by DDS_Condition_dispatch. If this parameter is null, an no-op handler implemenation will be set. |
struct DDS_ConditionHandler DDS_Condition_get_handler | ( | DDS_Condition * | self | ) |
<<extension>> Returns the registered DDS_ConditionHandler.
If no DDS_ConditionHandler is registered, this operation returns a no-op DDS_ConditionHandler implementation.
void DDS_Condition_dispatch | ( | DDS_Condition * | self | ) |
<<extension>> Calls DDS_ConditionHandler::on_condition_triggered of the registered DDS_ConditionHandler.
If the trigger value is true, calling this operation will call the registered.
If no DDS_ConditionHandler is registered, this operation is a no-op.
DDS_Condition * DDS_GuardCondition_as_condition | ( | DDS_GuardCondition * | guardCondition | ) |
Access a DDS_GuardCondition's supertype instance.
guardCondition | <<in>> Cannot be NULL. |
DDS_GuardCondition * DDS_GuardCondition_new | ( | void | ) |
No argument constructor.
Construct a new guard condition on the heap.
DDS_ReturnCode_t DDS_GuardCondition_delete | ( | DDS_GuardCondition * | self | ) |
Destructor.
Releases the resources associated with this object.
Deleting a NULL condition is safe and has no effect.
self | <<in>> Cannot be NULL. |
DDS_ReturnCode_t DDS_GuardCondition_set_trigger_value | ( | DDS_GuardCondition * | self, |
DDS_Boolean | value | ||
) |
DDS_Condition * DDS_StatusCondition_as_condition | ( | DDS_StatusCondition * | statusCondition | ) |
Access a DDS_StatusCondition's supertype instance.
statusCondition | <<in>> Cannot be NULL. |
DDS_StatusMask DDS_StatusCondition_get_enabled_statuses | ( | DDS_StatusCondition * | self | ) |
Get the list of statuses enabled on an DDS_Entity.
self | <<in>> Cannot be NULL. |
DDS_ReturnCode_t DDS_StatusCondition_set_enabled_statuses | ( | DDS_StatusCondition * | self, |
DDS_StatusMask | mask | ||
) |
This operation defines the list of communication statuses that determine the trigger_value
of the DDS_StatusCondition.
This operation may change the trigger_value
of the DDS_StatusCondition.
DDS_WaitSet objects' behavior depends on the changes of the trigger_value
of their attached conditions. Therefore, any DDS_WaitSet to which the DDS_StatusCondition is attached is potentially affected by this operation.
If this function is not invoked, the default list of enabled statuses includes all the statuses.
self | <<in>> Cannot be NULL. |
mask | <<in>> the list of enables statuses (see Status Kinds) |
DDS_Entity * DDS_StatusCondition_get_entity | ( | DDS_StatusCondition * | self | ) |
Get the DDS_Entity associated with the DDS_StatusCondition.
There is exactly one DDS_Entity assocated with each DDS_StatusCondition.
self | <<in>> Cannot be NULL. |
DDS_WaitSet * DDS_WaitSet_new | ( | void | ) |
Default no-argument constructor.
Construct a new DDS_WaitSet.
DDS_WaitSet * DDS_WaitSet_new_ex | ( | const struct DDS_WaitSetProperty_t * | prop | ) |
<<extension>> Constructor for a DDS_WaitSet 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 DDS_WaitSet.
DDS_ReturnCode_t DDS_WaitSet_delete | ( | DDS_WaitSet * | self | ) |
Destructor.
Releases the resources asociated with this DDS_WaitSet.
Freeing a null pointer is safe and does nothing.
self | <<in>> Cannot be NULL. |
DDS_ReturnCode_t DDS_WaitSet_set_property | ( | DDS_WaitSet * | self, |
const struct DDS_WaitSetProperty_t * | prop | ||
) |
<<extension>> Sets the DDS_WaitSetProperty_t, to configure the associated DDS_WaitSet to return after one or more trigger events have occurred.
DDS_ReturnCode_t DDS_WaitSet_get_property | ( | DDS_WaitSet * | self, |
struct DDS_WaitSetProperty_t * | prop | ||
) |
<<extension>> Retrieves the DDS_WaitSetProperty_t configuration of the associated DDS_WaitSet.
DDS_ReturnCode_t DDS_WaitSet_wait | ( | DDS_WaitSet * | self, |
struct DDS_ConditionSeq * | active_conditions, | ||
const struct DDS_Duration_t * | timeout | ||
) |
Allows an application thread to wait for the occurrence of certain conditions.
If none of the conditions attached to the DDS_WaitSet 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).
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 DDS_Condition objects are DDS_BOOLEAN_TRUE, wait fails with DDS_RETCODE_TIMEOUT. In this case, the resulting list of conditions will be empty. If a negative duration is passed, wait fails with DDS_RETCODE_BAD_PARAMETER.
Note: The resolution of the timeout
period is constrained by the resolution of the system clock.
When the DDS_WaitSet is configured to wait for more than one trigger event and the timeout is exceeded before that number is reached, this function returns normally as long as at least one trigger event has occurred.
It is not allowable for more than one application thread to be waiting on the same DDS_WaitSet. If the wait operation is invoked on a DDS_WaitSet that already has a thread blocking on it, the operation will return immediately with the value DDS_RETCODE_PRECONDITION_NOT_MET.
active_conditions | <<inout>> a valid non-NULL DDS_ConditionSeq object. Note that RTI Connext will not allocate a new object if active_conditions is NULL; the function will return DDS_RETCODE_PRECONDITION_NOT_MET. |
self | <<in>> Cannot be NULL. |
timeout | <<in>> a wait timeout |
DDS_ReturnCode_t DDS_WaitSet_attach_condition | ( | DDS_WaitSet * | self, |
DDS_Condition * | cond | ||
) |
Attaches a DDS_Condition to the DDS_WaitSet.
It is possible to attach a DDS_Condition on a DDS_WaitSet that is currently being waited upon (via the wait operation). In this case, if the DDS_Condition has a trigger_value
of DDS_BOOLEAN_TRUE, then attaching the condition will unblock the DDS_WaitSet.
DDS_ReturnCode_t DDS_WaitSet_detach_condition | ( | DDS_WaitSet * | self, |
DDS_Condition * | cond | ||
) |
Detaches a DDS_Condition from the DDS_WaitSet.
It is possible to detach a DDS_Condition on a DDS_WaitSet that is currently being waited upon (via the wait operation). If the DDS_Condition was not attached to the DDS_WaitSet, the operation will return DDS_RETCODE_BAD_PARAMETER.
DDS_ReturnCode_t DDS_WaitSet_get_conditions | ( | DDS_WaitSet * | self, |
struct DDS_ConditionSeq * | attached_conditions | ||
) |
Retrieves the list of attached DDS_Condition (s).
self | <<in>> Cannot be NULL. |
attached_conditions | <<inout>> a DDS_ConditionSeq object where the list of attached conditions will be returned |