Skip to content

Commit f0d53c2

Browse files
clalancetteMauro Passerino
authored andcommitted
Add locking to protect the TimeSource::NodeState::node_base_ (ros2#2320)
We need this because it is possible for one thread to be handling the on_parameter_event callback while another one is detaching the node. This lock will protect that from happening. Signed-off-by: Chris Lalancette <[email protected]>
1 parent aa99691 commit f0d53c2

File tree

1 file changed

+12
-5
lines changed

1 file changed

+12
-5
lines changed

rclcpp/src/rclcpp/time_source.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,7 @@ class TimeSource::NodeState final
250250
rclcpp::node_interfaces::NodeClockInterface::SharedPtr node_clock_interface,
251251
rclcpp::node_interfaces::NodeParametersInterface::SharedPtr node_parameters_interface)
252252
{
253+
std::lock_guard<std::mutex> guard(node_base_lock_);
253254
node_base_ = node_base_interface;
254255
node_topics_ = node_topics_interface;
255256
node_graph_ = node_graph_interface;
@@ -294,17 +295,14 @@ class TimeSource::NodeState final
294295
parameter_subscription_ = rclcpp::AsyncParametersClient::on_parameter_event(
295296
node_topics_,
296297
[this](std::shared_ptr<const rcl_interfaces::msg::ParameterEvent> event) {
297-
if (node_base_ != nullptr) {
298-
this->on_parameter_event(event);
299-
}
300-
// Do nothing if node_base_ is nullptr because it means the TimeSource is now
301-
// without an attached node
298+
this->on_parameter_event(event);
302299
});
303300
}
304301

305302
// Detach the attached node
306303
void detachNode()
307304
{
305+
std::lock_guard<std::mutex> guard(node_base_lock_);
308306
// destroy_clock_sub() *must* be first here, to ensure that the executor
309307
// can't possibly call any of the callbacks as we are cleaning up.
310308
destroy_clock_sub();
@@ -341,6 +339,7 @@ class TimeSource::NodeState final
341339
std::thread clock_executor_thread_;
342340

343341
// Preserve the node reference
342+
std::mutex node_base_lock_;
344343
rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_base_{nullptr};
345344
rclcpp::node_interfaces::NodeTopicsInterface::SharedPtr node_topics_{nullptr};
346345
rclcpp::node_interfaces::NodeGraphInterface::SharedPtr node_graph_{nullptr};
@@ -478,6 +477,14 @@ class TimeSource::NodeState final
478477
// Callback for parameter updates
479478
void on_parameter_event(std::shared_ptr<const rcl_interfaces::msg::ParameterEvent> event)
480479
{
480+
std::lock_guard<std::mutex> guard(node_base_lock_);
481+
482+
if (node_base_ == nullptr) {
483+
// Do nothing if node_base_ is nullptr because it means the TimeSource is now
484+
// without an attached node
485+
return;
486+
}
487+
481488
// Filter out events on 'use_sim_time' parameter instances in other nodes.
482489
if (event->node != node_base_->get_fully_qualified_name()) {
483490
return;

0 commit comments

Comments
 (0)