Hello all,
I have been experimenting for a while with listeners, conditions and waitsets to understand how they work exactly, since the DDS specification is a bit vague on some of the details of these features.
Based on the results I observed, a waitset with a StatusCondition attached to it is always woken up, independently of whether a listener is attached to the same Entity and enabled for the same status changes. Even if the status change event is consumed by the listener, the waitset will be unblocked and the StatusCondition will be returned by wait(). The StatusCondition is returned even if its trigger_value is certainly going to be False (at least with respect to that specific status change event - other events could occur before the StatusCondition is accessed by the application, which may cause its trigger_value to be True, but they should be handled independently - I'm not considering event batching in the Waitset).
This behavior brings me to two questions:
- Is it mandatory, according to the standard, to check the trigger_value of a Condition returned by a Waitset's wait()? This seems to be the case to guarantee correctness at the application level (and I understand it could be a synchronization nightmare to guarantee that a Condition will certainly be triggered when accessed by the application after having unblocked a Waitset), but the DDS spec seems to entail all Conditions will have trigger_value True ("It then uses the result of the wait (i.e., the list of Condition objects with trigger_value==TRUE) to actually get the information", bottom of pag.132) and it never explicitly require application to check it with get_trigger_value. Maybe this is just a case of miswording in the spec (if trigger_value=TRUE is not to be guaranteed, maybe something like "the list of Condition objects that had trigger_value = TRUE at any point during the wait" would have expressed the intended semantics better).
- Why is a Waitset always woken up, even if a Listener "consumed" a status change? Couldn't an implementation detect this eventuality (i.e. when the listener is called), determine that the StatusCondition will not be active because of this particular event and avoid waking up any Waitset associated with it? I think this goes hand in hand with the previous question. Admittedly there is nothing in the spec that says a Waitset will not be woken up if a listener consumed an event, but it does say that the trigger_value of a StatusCondition is the boolean OR of all the ChangedStatusFlag of the associated entity (btw, I'm assuming this is a typo and a ChangedStatusFlag is the same thing as a StatusChangedFlag, a few pages earlier). It also states that the StatusChangedFlag for a particular status is reset (i.e. set to FALSE) before a listener is called (I'm considering plain communication statuses, but it could be generalized to the read communication statuses too) and that listeners have precedence over waitsets/conditions. Isn't the StatusChangedFlag, and thus the trigger_value of a StatusCondition (at least with respect to that particular status), FALSE when the implementation logic gets to "deal with" the waitset, after calling a listener, and should make a decision on whether to unblock it or not?
Thanks,
-Andrea