Skip to content

Commit 0cef804

Browse files
Janosch MachowinskiJanosch Machowinski
authored andcommitted
fix: make Client goal handle recursive
This fixes deadlocks due to release of goal handles in callbacks etc. Signed-off-by: Janosch Machowinski <[email protected]>
1 parent 6f3cad7 commit 0cef804

File tree

1 file changed

+15
-11
lines changed

1 file changed

+15
-11
lines changed

rclcpp_action/include/rclcpp_action/client.hpp

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,7 @@ class Client : public ClientBase
448448
std::shared_ptr<GoalHandle> goal_handle(
449449
new GoalHandle(goal_info, options.feedback_callback, options.result_callback));
450450
{
451-
std::lock_guard<std::mutex> guard(goal_handles_mutex_);
451+
std::lock_guard<std::recursive_mutex> guard(goal_handles_mutex_);
452452
goal_handles_[goal_handle->get_goal_id()] = goal_handle;
453453
}
454454
promise->set_value(goal_handle);
@@ -466,7 +466,7 @@ class Client : public ClientBase
466466
// To prevent the list from growing out of control, forget about any goals
467467
// with no more user references
468468
{
469-
std::lock_guard<std::mutex> guard(goal_handles_mutex_);
469+
std::lock_guard<std::recursive_mutex> guard(goal_handles_mutex_);
470470
auto goal_handle_it = goal_handles_.begin();
471471
while (goal_handle_it != goal_handles_.end()) {
472472
if (!goal_handle_it->second.lock()) {
@@ -496,7 +496,7 @@ class Client : public ClientBase
496496
typename GoalHandle::SharedPtr goal_handle,
497497
ResultCallback result_callback = nullptr)
498498
{
499-
std::lock_guard<std::mutex> lock(goal_handles_mutex_);
499+
std::lock_guard<std::recursive_mutex> lock(goal_handles_mutex_);
500500
if (goal_handles_.count(goal_handle->get_goal_id()) == 0) {
501501
throw exceptions::UnknownGoalHandleError();
502502
}
@@ -531,7 +531,7 @@ class Client : public ClientBase
531531
typename GoalHandle::SharedPtr goal_handle,
532532
CancelCallback cancel_callback = nullptr)
533533
{
534-
std::lock_guard<std::mutex> lock(goal_handles_mutex_);
534+
std::lock_guard<std::recursive_mutex> lock(goal_handles_mutex_);
535535
if (goal_handles_.count(goal_handle->get_goal_id()) == 0) {
536536
throw exceptions::UnknownGoalHandleError();
537537
}
@@ -564,8 +564,12 @@ class Client : public ClientBase
564564

565565
void drop_goal_handle(typename GoalHandle::SharedPtr goal_handle)
566566
{
567-
std::lock_guard<std::mutex> guard(goal_handles_mutex_);
568-
const GoalUUID & goal_id = goal_handle->get_goal_id();
567+
drop_goal_handle(goal_handle->get_goal_id());
568+
}
569+
570+
void drop_goal_handle(const GoalUUID & goal_id)
571+
{
572+
std::lock_guard<std::recursive_mutex> guard(goal_handles_mutex_);
569573
if (goal_handles_.count(goal_id) == 0) {
570574
// someone else already deleted the entry
571575
// e.g. the result callback
@@ -605,7 +609,7 @@ class Client : public ClientBase
605609
virtual
606610
~Client()
607611
{
608-
std::lock_guard<std::mutex> guard(goal_handles_mutex_);
612+
std::lock_guard<std::recursive_mutex> guard(goal_handles_mutex_);
609613
auto it = goal_handles_.begin();
610614
while (it != goal_handles_.end()) {
611615
typename GoalHandle::SharedPtr goal_handle = it->second.lock();
@@ -652,7 +656,7 @@ class Client : public ClientBase
652656
void
653657
handle_feedback_message(std::shared_ptr<void> message) override
654658
{
655-
std::lock_guard<std::mutex> guard(goal_handles_mutex_);
659+
std::lock_guard<std::recursive_mutex> guard(goal_handles_mutex_);
656660
using FeedbackMessage = typename ActionT::Impl::FeedbackMessage;
657661
typename FeedbackMessage::SharedPtr feedback_message =
658662
std::static_pointer_cast<FeedbackMessage>(message);
@@ -689,7 +693,7 @@ class Client : public ClientBase
689693
void
690694
handle_status_message(std::shared_ptr<void> message) override
691695
{
692-
std::lock_guard<std::mutex> guard(goal_handles_mutex_);
696+
std::lock_guard<std::recursive_mutex> guard(goal_handles_mutex_);
693697
using GoalStatusMessage = typename ActionT::Impl::GoalStatusMessage;
694698
auto status_message = std::static_pointer_cast<GoalStatusMessage>(message);
695699
for (const GoalStatus & status : status_message->status_list) {
@@ -730,7 +734,7 @@ class Client : public ClientBase
730734
std::static_pointer_cast<void>(goal_result_request),
731735
[goal_id, this](std::shared_ptr<void> response) mutable
732736
{
733-
std::lock_guard<std::mutex> lock(goal_handles_mutex_);
737+
std::lock_guard<std::recursive_mutex> lock(goal_handles_mutex_);
734738
if (goal_handles_.count(goal_id) == 0) {
735739
RCLCPP_DEBUG(
736740
this->get_logger(),
@@ -787,7 +791,7 @@ class Client : public ClientBase
787791
}
788792

789793
std::map<GoalUUID, typename GoalHandle::WeakPtr> goal_handles_;
790-
std::mutex goal_handles_mutex_;
794+
std::recursive_mutex goal_handles_mutex_;
791795
};
792796
} // namespace rclcpp_action
793797

0 commit comments

Comments
 (0)