Skip to content

Commit be0477a

Browse files
mauropasseMauro Passerino
authored andcommitted
Declare rclcpp callbacks before the rcl entities (ros2#2024)
This is to ensure callbacks are destroyed last on entities destruction, avoiding the gap in time in which rmw entities hold a reference to a destroyed function. Signed-off-by: Mauro Passerino <[email protected]> Co-authored-by: Mauro Passerino <[email protected]>
1 parent e97d4e8 commit be0477a

File tree

3 files changed

+22
-9
lines changed

3 files changed

+22
-9
lines changed

rclcpp/include/rclcpp/client.hpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -359,12 +359,16 @@ class ClientBase
359359
std::shared_ptr<rclcpp::Context> context_;
360360
rclcpp::Logger node_logger_;
361361

362+
std::recursive_mutex callback_mutex_;
363+
// It is important to declare on_new_response_callback_ before
364+
// client_handle_, so on destruction the client is
365+
// destroyed first. Otherwise, the rmw client callback
366+
// would point briefly to a destroyed function.
367+
std::function<void(size_t)> on_new_response_callback_{nullptr};
368+
// Declare client_handle_ after callback
362369
std::shared_ptr<rcl_client_t> client_handle_;
363370

364371
std::atomic<bool> in_use_by_wait_set_{false};
365-
366-
std::recursive_mutex callback_mutex_;
367-
std::function<void(size_t)> on_new_response_callback_{nullptr};
368372
};
369373

370374
template<typename ServiceT>

rclcpp/include/rclcpp/service.hpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -262,15 +262,19 @@ class ServiceBase
262262

263263
std::shared_ptr<rcl_node_t> node_handle_;
264264

265+
std::recursive_mutex callback_mutex_;
266+
// It is important to declare on_new_request_callback_ before
267+
// service_handle_, so on destruction the service is
268+
// destroyed first. Otherwise, the rmw service callback
269+
// would point briefly to a destroyed function.
270+
std::function<void(size_t)> on_new_request_callback_{nullptr};
271+
// Declare service_handle_ after callback
265272
std::shared_ptr<rcl_service_t> service_handle_;
266273
bool owns_rcl_handle_ = true;
267274

268275
rclcpp::Logger node_logger_;
269276

270277
std::atomic<bool> in_use_by_wait_set_{false};
271-
272-
std::recursive_mutex callback_mutex_;
273-
std::function<void(size_t)> on_new_request_callback_{nullptr};
274278
};
275279

276280
template<typename ServiceT>

rclcpp/include/rclcpp/subscription_base.hpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,14 @@ class SubscriptionBase : public std::enable_shared_from_this<SubscriptionBase>
557557
rclcpp::node_interfaces::NodeBaseInterface * const node_base_;
558558

559559
std::shared_ptr<rcl_node_t> node_handle_;
560+
561+
std::recursive_mutex callback_mutex_;
562+
// It is important to declare on_new_message_callback_ before
563+
// subscription_handle_, so on destruction the subscription is
564+
// destroyed first. Otherwise, the rmw subscription callback
565+
// would point briefly to a destroyed function.
566+
std::function<void(size_t)> on_new_message_callback_{nullptr};
567+
// Declare subscription_handle_ after callback
560568
std::shared_ptr<rcl_subscription_t> subscription_handle_;
561569
std::shared_ptr<rcl_subscription_t> intra_process_subscription_handle_;
562570
rclcpp::Logger node_logger_;
@@ -579,9 +587,6 @@ class SubscriptionBase : public std::enable_shared_from_this<SubscriptionBase>
579587
std::atomic<bool> intra_process_subscription_waitable_in_use_by_wait_set_{false};
580588
std::unordered_map<rclcpp::QOSEventHandlerBase *,
581589
std::atomic<bool>> qos_events_in_use_by_wait_set_;
582-
583-
std::recursive_mutex callback_mutex_;
584-
std::function<void(size_t)> on_new_message_callback_{nullptr};
585590
};
586591

587592
} // namespace rclcpp

0 commit comments

Comments
 (0)