-
Notifications
You must be signed in to change notification settings - Fork 365
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Call dds_entity_status_set independently of enabled #699
Call dds_entity_status_set independently of enabled #699
Conversation
The interaction between listeners and waitsets is a bit of a mess in DDS, or more precisely, the spec tries to avoid a mess by making life complicated. It says somewhere that the listeners must be invoked prior to triggering waitsets. Typically, the listener does something that resets the condition, after which the waitset would not trigger anymore. I agree that it looks like Cyclone currently doesn't even set the status when there is a listener to invoke, presumably on the (incorrect) assumption that the listener would reset it anyway and/or that no-one would be silly enough to actually try to combine listeners and waitsets for the same event. Setting the status after invoking the listener is wrong, because then the listener can't handle it and prevent the waitset from triggering. If anything, it needs to be set prior to calling the listener, and then triggering the waitsets if the status is still set after the listener execution. But before making such a change to the behaviour, I'd better re-read the part of the spec that is about listener/waitset interaction to be certain that the status indeed must be set prior to calling the listener (it seems logical, but ...) and that I understand what it does to if multiple threads are it at the same time. Regarding that final remark, suppose I have two threads, one sets status A and the other sets status B, and both A and B have listeners and both are waited on in a waitset. Then one wonders what "listeners must be invoked prior to triggering waitsets" means for the following schedule: T1: set A where I'm wondering of T3 may observe B in the status flags ... And as a final remark: I'm quite pleased that a whole bunch of listener tests fails with this change 🙂 |
Hi @eboasson, thanks for your comment! |
Otherwise if an event listener callback is defined (invoke=true) dds_entity_status_set is not called, so the ROS2 waitset based executors can't identify when an event happened. This commit enables support for events and waitset based executors. Signed-off-by: Mauro Passerino <mpasserino@irobot.com>
ca3d06a
to
fbbb444
Compare
This commit is not a solution, its purpose is just to show where the issue is
@mauropasse thank you very much for your efforts trying make sense of the inner workings of listeners + waitset triggering and trying to fix this behaviour. (I'm writing "fix" here, I understand the logic behind your desire even though I have my reservations whether the spec'd behaviour really is something desirable.) As I'm sure you've seen, it is rather tricky to do this, for example, there is this rule that says take/read reset the That in turn opens up interesting possibilities for race conditions, TOCTTOU problems and whatnot, but I don't see an alternative just yet. I've tried doing that in https://github.com/eboasson/cyclonedds/tree/waitset-listener-interaction but I have my doubts about it. Still, with a more changes in tests that were failing because they explicitly checked that the status would be cleared if the listener got invoked, it does pass the CI. Perhaps you would like to have a look? |
Hi @eboasson, thanks for working on this! "if both mechanisms are enabled, then the listener mechanism is used first and then the WaitSet objects are signalled" (2.2.4.6) So your commit still matches the DDS specification, correct me if I'm wrong:
So you say that all tests pass (removing tests which checked status cleared after listener invocation). That's awesome! About the race conditions and issues you mention, I think the function is not thread safe even with your new changes. Couldn't be all of this protected under a mutex? |
Hi @eboasson, I tested your branch and I confirm that with it the rclcpp tests succeeds |
Closing since #900 did the job |
Call dds_entity_status_set independently of enabled
Otherwise if an event listener callback is defined (invoke=true) dds_entity_status_set is not called, so the ROS2 waitset based executors can't identify when an event happened. This commit supports both events & waiset based ROS2 executors.