-
Notifications
You must be signed in to change notification settings - Fork 522
Description
Bug report
Required Info:
- Operating System:
- All
- Installation type:
- All
- Version or commit hash:
- be8c5d0 (i.e. today's HEAD)
- DDS implementation:
- All
- Client library (if applicable):
- rclcpp
Steps to reproduce issue
This is a rough sketch of what we are trying in nav2. I doubt anything this complicated is needed. Probably just making two arbitrary callbacks and registering them in different orders will repro the issue. You just need to beat the hash algorithm basically.
class MyChild : public rclcpp::LifecycleNode {
MyChild() {
register_my_rcl_preshutdown_callback();
}
...
};
class MyDescendant : public MyChild
{
MyDescendant() : MyChild(blah) {
// Super constructor already ran by this point, so the MyDescendant
// instance should have its preshutdown callback called before my_member's
// preshutdown callback, but we are sometimes seeing them in reverse order!
auto my_member = std::make_shared<MyChild>(blah);
}
...
};
Actual behavior
In nav2 we are working on a fix which uses the preshutdown callback mechanism. A pair of callbacks are sometimes firing in the reverse order from which they were added.
It looks like both preshutdown callbacks and on shutdown callbacks use an unordered_set:
rclcpp/rclcpp/include/rclcpp/context.hpp
Line 379 in 37adc03
| std::unordered_set<std::shared_ptr<OnShutdownCallback>> on_shutdown_callbacks_; |
And they are executed via an iteration of those sets, which I believe means they will execute in some arbitrary hash order?
rclcpp/rclcpp/src/rclcpp/context.cpp
Line 315 in 37adc03
| for (const auto & callback : pre_shutdown_callbacks_) { |
Expected behavior
But the docs state pretty clearly that callbacks will be executed in the order they are added:
rclcpp/rclcpp/include/rclcpp/context.hpp
Line 228 in 37adc03
| * These callbacks will be called in the order they are added as the second |
rclcpp/rclcpp/include/rclcpp/context.hpp
Line 178 in 37adc03
| * - each on_shutdown callback is called, in the order that they were added |
Seems like the docs are mismatched to the implementation. Unfortunately it may be annoying to reproduce since this involves a hash function... Might need to make a custom hash function to reproduce it.
Additional information
Can we please also add another line to the Context::shutdown docs regarding the preshutdown callbacks? Thanks to the people who added that callback; super handy!