From c628cc4c81178afb3fe655889d84997068a9390d Mon Sep 17 00:00:00 2001 From: Mauro Passerino Date: Mon, 10 Oct 2022 15:06:02 +0100 Subject: [PATCH] Declare rclcpp callbacks before the rcl entities 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 --- rclcpp/include/rclcpp/client.hpp | 10 +++++++--- rclcpp/include/rclcpp/service.hpp | 1 - rclcpp/include/rclcpp/subscription_base.hpp | 11 ++++++++--- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/rclcpp/include/rclcpp/client.hpp b/rclcpp/include/rclcpp/client.hpp index 61732c7d4e..e2c56c5f07 100644 --- a/rclcpp/include/rclcpp/client.hpp +++ b/rclcpp/include/rclcpp/client.hpp @@ -388,6 +388,13 @@ class ClientBase std::shared_ptr context_; rclcpp::Logger node_logger_; + std::recursive_mutex callback_mutex_; + // It is important to declare on_new_response_callback_ before + // client_handle_, so on destruction the client is + // destroyed first. Otherwise, the rmw client callback + // would point briefly to a destroyed function. + std::function on_new_response_callback_{nullptr}; + // Declare client_handle_ after callback std::shared_ptr client_handle_; std::atomic in_use_by_wait_set_{false}; @@ -396,9 +403,6 @@ class ClientBase bool use_intra_process_{false}; IntraProcessManagerWeakPtr weak_ipm_; uint64_t intra_process_client_id_; - - std::recursive_mutex callback_mutex_; - std::function on_new_response_callback_{nullptr}; }; template diff --git a/rclcpp/include/rclcpp/service.hpp b/rclcpp/include/rclcpp/service.hpp index 11e49883db..4c0c3ae5d7 100644 --- a/rclcpp/include/rclcpp/service.hpp +++ b/rclcpp/include/rclcpp/service.hpp @@ -302,7 +302,6 @@ class ServiceBase // would point briefly to a destroyed function. std::function on_new_request_callback_{nullptr}; // Declare service_handle_ after callback - std::shared_ptr service_handle_; bool owns_rcl_handle_ = true; diff --git a/rclcpp/include/rclcpp/subscription_base.hpp b/rclcpp/include/rclcpp/subscription_base.hpp index 04e7961316..d14142ddee 100644 --- a/rclcpp/include/rclcpp/subscription_base.hpp +++ b/rclcpp/include/rclcpp/subscription_base.hpp @@ -558,6 +558,14 @@ class SubscriptionBase : public std::enable_shared_from_this rclcpp::node_interfaces::NodeBaseInterface * const node_base_; std::shared_ptr node_handle_; + + std::recursive_mutex callback_mutex_; + // It is important to declare on_new_message_callback_ before + // subscription_handle_, so on destruction the subscription is + // destroyed first. Otherwise, the rmw subscription callback + // would point briefly to a destroyed function. + std::function on_new_message_callback_{nullptr}; + // Declare subscription_handle_ after callback std::shared_ptr subscription_handle_; std::shared_ptr intra_process_subscription_handle_; rclcpp::Logger node_logger_; @@ -580,9 +588,6 @@ class SubscriptionBase : public std::enable_shared_from_this std::atomic intra_process_subscription_waitable_in_use_by_wait_set_{false}; std::unordered_map> qos_events_in_use_by_wait_set_; - - std::recursive_mutex callback_mutex_; - std::function on_new_message_callback_{nullptr}; }; } // namespace rclcpp