Index

Package: DDS.WaitSet

Description

package DDS.WaitSet is

Summary: <<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.

Usage

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:

  • The application indicates which relevant information it wants to get by creating DDS.Condition objects (DDS.StatusCondition, DDS.ReadCondition or DDS.QueryCondition) and attaching them to a DDS.WaitSet.

  • It then waits on that DDS.WaitSet until the trigger_value of one or several DDS.Condition objects become DDS.BOOLEAN_TRUE.

  • It then uses the result of the wait (i.e., 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;
    • by calling directly FooDataReader.read_w_condition or FooDataReader.take_w_condition on a DDS.DataReader with the DDS.Condition as a parameter if it is a DDS.ReadCondition or a DDS.QueryCondition.

    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.


    DDS.WaitSet 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.

    Trigger State of a DDS.StatusCondition

    The trigger_value of a DDS.StatusCondition is the boolean OR of the ChangedStatusFlag of all the communication statuses (see DDSStatusTypesModule) 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.

    Trigger State of a DDS.ReadCondition

    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 dds). 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.

    Trigger State of a DDS.GuardCondition

    The trigger_value of a DDS.GuardCondition is completely controlled by the application via the operation DDS.GuardCondition.set_trigger_value.

    Important: The DDS.WaitSet allocates native resources. When DDS.WaitSet is no longer being used, user should call DDSWaitSet::~DDSWaitSet() explicitly to properly cleanup all native resources.


    See also: DDSStatusTypesModule
    See also: DDS.StatusCondition, DDS.GuardCondition
    See also: DDS.Listener

  • Classes

    Ref

    type Ref is new Ada.Finalization.Limited_Controlled with private;

    Ancestors:

    Limited_Controlled

    Primitive operations:

    Attach_Condition
    Detach_Condition
    Finalize (overriding Finalize)
    Get_Conditions
    Get_Property
    Initialize (overriding Initialize)
    Set_Property

    Summary: Default no-argument constructor.

    Construct a new DDS.WaitSet.

    MT Safety:
    UNSAFE. In VxWorks, it is unsafe to call this procedure while another thread may be simultaneously calling DDS.DomainParticipantFactory.get_instance, DDS.DomainParticipantFactory.finalize_instance, DDS_TypeCodeFactory.get_instance, DDSGuardCondition::DDSGuardCondition, DDSWaitSet::DDSWaitSet(), DDSWaitSet::DDSWaitSet(const DDS_WaitSetProperty_t&), DDSGuardCondition::~DDSGuardCondition, DDSWaitSet::~DDSWaitSet(), NDDSUtilityNetworkCapture.enable, or NDDSUtilityNetworkCapture.disable.

    Important: WaitSet allocates native resources. When a WaitSet is no longer being used, close() must be called.

    Raises: DDS.RETCODE_OUT_OF_RESOURCES if a new DDS.WaitSet could not be allocated.

    \elseif C_LANGUAGE_ONLY Returns: A new DDS.WaitSet or ull_value if one could not be allocated.

    Types

    Ref_Access

    type Ref_Access is access all Ref'Class;

    Subprograms & Entries

    Initialize

    procedure Initialize 
    (Self: in out Ref);

    Finalize

    procedure Finalize 
    (Self: in out Ref);

    Wait

    procedure Wait 
    (Self: not null access Ref;
    Active_Conditions: access DDS.ConditionSeq.Sequence;
    Timeout: in DDS.Duration_T);

    Summary: 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- ull_value DDSConditionSeq object. Note that RTI Connext will not allocate a new object if active_conditions is ull_value; the procedure will return DDS.RETCODE_PRECONDITION_NOT_MET.

    self: <<in>> Cannot be NULL

    timeout: <<in>> a wait timeout

    Raises: One of the DDSReturnTypesModule_std_retcodes or DDS.RETCODE_PRECONDITION_NOT_MET or DDS.RETCODE_TIMEOUT.

    Wait

    procedure Wait 
    (Self: not null access Ref;
    Active_Conditions: access DDS.ConditionSeq.Sequence;
    Timeout: in Duration);

    Summary: 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- ull_value DDSConditionSeq object. Note that RTI Connext will not allocate a new object if active_conditions is ull_value; the procedure will return DDS.RETCODE_PRECONDITION_NOT_MET.

    self: <<in>> Cannot be NULL

    timeout: <<in>> a wait timeout

    Raises: One of the DDSReturnTypesModule_std_retcodes or DDS.RETCODE_PRECONDITION_NOT_MET or DDS.RETCODE_TIMEOUT.

    Attach_Condition

    procedure Attach_Condition 
    (Self: not null access Ref;
    Cond: access DDS.Condition.Ref'Class);

    Summary: 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.

    self: <<in>> Cannot be NULL

    cond: <<in>> Condition to be attached.

    Raises: One of the DDSReturnTypesModule_std_retcodes, or DDS.RETCODE_OUT_OF_RESOURCES.

    Detach_Condition

    procedure Detach_Condition 
    (Self: not null access Ref;
    Cond: access DDS.Condition.Ref'Class);

    Summary: 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.

    self: <<in>> Cannot be NULL

    cond: <<in>> Condition to be detached.

    Raises: One of the DDSReturnTypesModule_std_retcodes, or DDS.RETCODE_PRECONDITION_NOT_MET.

    Get_Conditions

    procedure Get_Conditions 
    (Self: not null access Ref;
    Attached_Conditions: access DDS.ConditionSeq.Sequence);

    Summary: Retrieves the list of attached DDS.Condition (s).

    self: <<in>> Cannot be NULL

    attached_conditions: <<inout>> a DDSConditionSeq object where the list of attached conditions will be returned

    Raises: One of the DDSReturnTypesModule_std_retcodes, or DDS.RETCODE_PRECONDITION_NOT_MET.

    Free

    procedure Free 
    (This: in out Ref_Access);

    Summary: Destructor.

    Releases the resources asociated with this DDS.WaitSet.

    Calling this method multiple times on the same DDS.WaitSet is safe; subsequent deletions will have no effect. NDDSUtilityNetworkCapture.enable, or NDDSUtilityNetworkCapture.disable.

    self: <<in>> Cannot be NULL

    \endif

    Set_Property

    procedure Set_Property 
    (Self: not null access Ref;
    prop: access WaitSetProperty_T);

    Summary: <<ext>> Sets the DDS.WaitSetProperty_t, to configure the associated DDS.WaitSet to return after one or more trigger events have occurred.

    self: <<in>> Cannot be NULL

    prop: <<in>>

    Raises: One of the DDSReturnTypesModule_std_retcodes

    Get_Property

    procedure Get_Property 
    (Self: not null access Ref;
    prop: access WaitSetProperty_T);

    Summary: <<ext>> Retrieves the DDS.WaitSetProperty_t configuration of the associated DDS.WaitSet.

    self: <<in>> Cannot be NULL

    prop: <<out>>

    Raises: One of the DDSReturnTypesModule_std_retcodes