From 7628893d2c3cd5afe173b34db15b0d1c3217c3de Mon Sep 17 00:00:00 2001
From: Rainer Kartmann <rainer.kartmann@kit.edu>
Date: Wed, 17 May 2023 11:59:02 +0200
Subject: [PATCH] Fix deadlock in skill provider when abortSkill() calls itself
 indirectly

---
 .../manager/SkillManagerComponentPlugin.cpp   | 22 ++++++++++++++++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.cpp b/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.cpp
index 38ca6ea50..455215311 100644
--- a/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.cpp
+++ b/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.cpp
@@ -82,6 +82,9 @@ namespace armarx
         return "INVALID PROVIDER NAME";
     }
 
+    using SkillProviderInterfacePrxMap =
+        std::map<std::string, skills::provider::dti::SkillProviderInterfacePrx>;
+
     skills::provider::dto::SkillStatusUpdate
     SkillManagerComponentPluginUser::executeSkill(
         const skills::manager::dto::SkillExecutionRequest& info,
@@ -97,6 +100,12 @@ namespace armarx
             providerName = info.skillId.providerName;
         }
 
+        SkillProviderInterfacePrxMap skillProviderMap;
+        {
+            std::scoped_lock l(skillProviderMapMutex);
+            skillProviderMap = this->skillProviderMap;
+        }
+
         bool remove = false;
         if (auto it = skillProviderMap.find(providerName); it != skillProviderMap.end())
         {
@@ -124,6 +133,8 @@ namespace armarx
             if (remove)
             {
                 std::scoped_lock l(skillProviderMapMutex);
+                // No copy!
+                SkillProviderInterfacePrxMap& skillProviderMap = this->skillProviderMap;
                 if (auto it = skillProviderMap.find(providerName); it != skillProviderMap.end())
                 {
                     ARMARX_WARNING << __PRETTY_FUNCTION__ << ": Found disconnected skill provider '"
@@ -149,7 +160,12 @@ namespace armarx
                                                 const std::string& skillName,
                                                 const Ice::Current& current)
     {
-        std::scoped_lock l(skillProviderMapMutex);
+        SkillProviderInterfacePrxMap skillProviderMap;
+        {
+            std::scoped_lock l(skillProviderMapMutex);
+            skillProviderMap = this->skillProviderMap;
+        }
+
         if (auto it = skillProviderMap.find(providerName); it != skillProviderMap.end())
         {
             const auto& n = it->first;
@@ -160,8 +176,8 @@ namespace armarx
             }
             else
             {
-                ARMARX_WARNING << __PRETTY_FUNCTION__ << ": Found disconnected skill provider '" << n << "'. Removing it from skills.";
-                it = skillProviderMap.erase(it);
+                ARMARX_WARNING << __PRETTY_FUNCTION__ << ": Found disconnected skill provider '"
+                               << n << "'. Removing it from skills on next execute.";
             }
         }
     }
-- 
GitLab