Skip to content
Snippets Groups Projects
Commit 19de5282 authored by Julian Tusch's avatar Julian Tusch :no_entry_sign:
Browse files

fixed errors (deadlock, segfaults)

parent 198f1116
No related branches found
No related tags found
2 merge requests!459fluxio/dev Pointer Shenanigans,!449Fluxio preliminary release
Pipeline #19672 canceled
...@@ -855,7 +855,7 @@ namespace armarx::plugins ...@@ -855,7 +855,7 @@ namespace armarx::plugins
s.executable = false; s.executable = false;
s.native = true; s.native = true;
std::shared_lock providersLock_shared(fluxioDC.providersMutex); std::unique_lock providersLock(fluxioDC.providersMutex);
const auto& providersEntry = const auto& providersEntry =
fluxioDC.providers.find(boost::uuids::to_string(providerId)); fluxioDC.providers.find(boost::uuids::to_string(providerId));
if (providersEntry != fluxioDC.providers.end()) if (providersEntry != fluxioDC.providers.end())
...@@ -864,19 +864,18 @@ namespace armarx::plugins ...@@ -864,19 +864,18 @@ namespace armarx::plugins
} }
else else
{ {
providersLock_shared.unlock();
std::unique_lock providersLock_unique(fluxioDC.providersMutex);
const auto p = addFluxioProvider(skillId.providerId->providerName); const auto p = addFluxioProvider(skillId.providerId->providerName);
if (p == nullptr) if (p == nullptr)
{ {
ARMARX_WARNING << "Failed to add provider with name '" ARMARX_WARNING << "Failed to add provider with name '"
<< skillId.providerId->providerName << "'."; << skillId.providerId->providerName << "'. Skill '" << s.name
providersLock_unique.unlock(); << " (" << s.id << ")' will not be added.";
providersLock.unlock();
continue; continue;
} }
s.skillProviderPtr = p; s.skillProviderPtr = p;
providersLock_unique.unlock();
} }
providersLock.unlock();
// add default control flow parameters // add default control flow parameters
skills::FluxioParameter start; skills::FluxioParameter start;
...@@ -965,15 +964,15 @@ namespace armarx::plugins ...@@ -965,15 +964,15 @@ namespace armarx::plugins
{ {
std::shared_lock l(fluxioDC.skillsMutex); std::shared_lock l(fluxioDC.skillsMutex);
const auto& skillsEntry = fluxioDC.skills.find(id); const auto& skillsEntry = fluxioDC.skills.find(id);
if (skillsEntry != fluxioDC.skills.end()) if (skillsEntry == fluxioDC.skills.end())
{ {
ARMARX_WARNING << "Skill with id '" << id << "' not found.";
l.unlock(); l.unlock();
return std::experimental::make_observer(&skillsEntry->second); return nullptr;
} }
ARMARX_WARNING << "Skill with id '" << id << "' not found.";
l.unlock(); l.unlock();
return nullptr; return std::experimental::make_observer(&skillsEntry->second);
} }
std::optional<std::vector<std::experimental::observer_ptr<const skills::FluxioSkill>>> std::optional<std::vector<std::experimental::observer_ptr<const skills::FluxioSkill>>>
...@@ -1017,6 +1016,12 @@ namespace armarx::plugins ...@@ -1017,6 +1016,12 @@ namespace armarx::plugins
for (const auto& [nodeId, node] : s.nodes) for (const auto& [nodeId, node] : s.nodes)
{ {
if (node == nullptr)
{
ARMARX_WARNING << "Unexpected nullptr!";
continue;
}
if (node->nodeType == skills::FluxioNodeType::SUBSKILL) if (node->nodeType == skills::FluxioNodeType::SUBSKILL)
{ {
// cast to the right node type // cast to the right node type
...@@ -1062,8 +1067,7 @@ namespace armarx::plugins ...@@ -1062,8 +1067,7 @@ namespace armarx::plugins
ARMARX_WARNING << "Updating affected skills."; ARMARX_WARNING << "Updating affected skills.";
for (const auto& affectedSkill : affectedSkills) for (const auto& affectedSkill : affectedSkills)
{ {
const_cast<skills::FluxioSkill*>(affectedSkill.get()) affectedSkill->removeSubSkillNodesAndEdges(skillId);
->removeSubSkillNodesAndEdges(skillId);
} }
ARMARX_WARNING << "Deleting skill '" << skillIt->second.name << "' (" << skillId ARMARX_WARNING << "Deleting skill '" << skillIt->second.name << "' (" << skillId
...@@ -1129,20 +1133,20 @@ namespace armarx::plugins ...@@ -1129,20 +1133,20 @@ namespace armarx::plugins
std::shared_lock l(fluxioDC.profilesMutex); std::shared_lock l(fluxioDC.profilesMutex);
const auto& profilesEntry = fluxioDC.profiles.find(id); const auto& profilesEntry = fluxioDC.profiles.find(id);
if (profilesEntry != fluxioDC.profiles.end()) if (profilesEntry == fluxioDC.profiles.end())
{ {
l.unlock(); l.unlock();
return profilesEntry->second; return std::nullopt;
} }
l.unlock(); l.unlock();
return std::nullopt; return profilesEntry->second;
} }
skills::FluxioProfile skills::FluxioProfile
SkillManagerComponentPlugin::createProfile(const skills::FluxioProfile& profile) SkillManagerComponentPlugin::createProfile(const skills::FluxioProfile& profile)
{ {
std::string id = IceUtil::generateUUID(); // TODO: use boost library for uuids std::string id = IceUtil::generateUUID();
std::unique_lock l(fluxioDC.profilesMutex); std::unique_lock l(fluxioDC.profilesMutex);
fluxioDC.profiles[id] = profile; // a copy is created when the profile is added to the map fluxioDC.profiles[id] = profile; // a copy is created when the profile is added to the map
...@@ -1173,24 +1177,22 @@ namespace armarx::plugins ...@@ -1173,24 +1177,22 @@ namespace armarx::plugins
{ {
const std::string& providerId = boost::uuids::to_string(createUuidWithString(name)); const std::string& providerId = boost::uuids::to_string(createUuidWithString(name));
std::shared_lock providersLock_shared(fluxioDC.providersMutex); std::unique_lock l(fluxioDC.providersMutex);
if (fluxioDC.providers.find(providerId) != fluxioDC.providers.end()) if (fluxioDC.providers.find(providerId) != fluxioDC.providers.end())
{ {
ARMARX_WARNING << "Provider with name '" << name << "' already exists."; ARMARX_WARNING << "Provider with name '" << name << "' already exists.";
return std::experimental::make_observer(&fluxioDC.providers[providerId]); return std::experimental::make_observer(&fluxioDC.providers[providerId]);
providersLock_shared.unlock(); l.unlock();
return nullptr; return nullptr;
} }
providersLock_shared.unlock();
skills::FluxioProvider p; skills::FluxioProvider p;
p.id = providerId; p.id = providerId;
p.name = name; p.name = name;
std::unique_lock providersLock_unique(fluxioDC.providersMutex);
fluxioDC.providers[p.id] = p; fluxioDC.providers[p.id] = p;
const auto& ret = std::experimental::make_observer(&fluxioDC.providers[p.id]); const auto& ret = std::experimental::make_observer(&fluxioDC.providers[p.id]);
providersLock_unique.unlock(); l.unlock();
return ret; return ret;
} }
...@@ -1352,7 +1354,7 @@ namespace armarx::plugins ...@@ -1352,7 +1354,7 @@ namespace armarx::plugins
const std::string& userId, const std::string& userId,
const std::string& skillId) const std::string& skillId)
{ {
std::shared_lock mutexMapLock_shared(fluxioDC.skillMutexMapMutex); std::scoped_lock l(fluxioDC.skillMutexMapMutex);
const auto& skillMutexIt = fluxioDC.skillMutexMap.find(skillId); const auto& skillMutexIt = fluxioDC.skillMutexMap.find(skillId);
// aquire mutex // aquire mutex
...@@ -1361,10 +1363,7 @@ namespace armarx::plugins ...@@ -1361,10 +1363,7 @@ namespace armarx::plugins
if (skillMutexIt == fluxioDC.skillMutexMap.end()) if (skillMutexIt == fluxioDC.skillMutexMap.end())
{ {
// skill is free, set mutex // skill is free, set mutex
mutexMapLock_shared.unlock();
std::unique_lock mutexMapLock_unique(fluxioDC.skillMutexMapMutex);
fluxioDC.skillMutexMap[skillId] = std::make_tuple(userId, armarx::DateTime::Now()); fluxioDC.skillMutexMap[skillId] = std::make_tuple(userId, armarx::DateTime::Now());
mutexMapLock_unique.unlock();
return true; return true;
} }
...@@ -1372,10 +1371,7 @@ namespace armarx::plugins ...@@ -1372,10 +1371,7 @@ namespace armarx::plugins
if (std::get<0>(fluxioDC.skillMutexMap[skillId]) == userId) if (std::get<0>(fluxioDC.skillMutexMap[skillId]) == userId)
{ {
// user already holds the mutex -> reset timestamp / prolong mutex // user already holds the mutex -> reset timestamp / prolong mutex
mutexMapLock_shared.unlock();
std::unique_lock mutexMapLock_unique(fluxioDC.skillMutexMapMutex);
std::get<1>(fluxioDC.skillMutexMap[skillId]) = armarx::DateTime::Now(); std::get<1>(fluxioDC.skillMutexMap[skillId]) = armarx::DateTime::Now();
mutexMapLock_unique.unlock();
return true; return true;
} }
...@@ -1385,15 +1381,11 @@ namespace armarx::plugins ...@@ -1385,15 +1381,11 @@ namespace armarx::plugins
if (elapsedTime.toMinutes() > fluxioDC.mutexTimeout) if (elapsedTime.toMinutes() > fluxioDC.mutexTimeout)
{ {
// mutex invalid, requesting user gets the mutex instead // mutex invalid, requesting user gets the mutex instead
mutexMapLock_shared.unlock();
std::unique_lock mutexMapLock_unique(fluxioDC.skillMutexMapMutex);
fluxioDC.skillMutexMap[skillId] = std::make_tuple(userId, armarx::DateTime::Now()); fluxioDC.skillMutexMap[skillId] = std::make_tuple(userId, armarx::DateTime::Now());
mutexMapLock_unique.unlock();
return true; return true;
} }
// mutex could not be aquired // mutex could not be aquired
mutexMapLock_shared.unlock();
return false; return false;
} }
...@@ -1401,22 +1393,17 @@ namespace armarx::plugins ...@@ -1401,22 +1393,17 @@ namespace armarx::plugins
if (skillMutexIt == fluxioDC.skillMutexMap.end()) if (skillMutexIt == fluxioDC.skillMutexMap.end())
{ {
// skill is already free // skill is already free
mutexMapLock_shared.unlock();
return true; return true;
} }
// check if the user holds the mutex, as only the user that holds the mutex can release it // check if the user holds the mutex, as only the user that holds the mutex can release it
if (std::get<0>(fluxioDC.skillMutexMap[skillId]) == userId) if (std::get<0>(fluxioDC.skillMutexMap[skillId]) == userId)
{ {
mutexMapLock_shared.unlock();
std::unique_lock mutexMapLock_unique(fluxioDC.skillMutexMapMutex);
fluxioDC.skillMutexMap.erase(skillId); fluxioDC.skillMutexMap.erase(skillId);
mutexMapLock_unique.unlock();
return true; return true;
} }
// mutex could not be removed // mutex could not be removed
mutexMapLock_shared.unlock();
return false; return false;
} }
} // namespace armarx::plugins } // namespace armarx::plugins
#include "SkillManagerComponentPluginUser.h" #include "SkillManagerComponentPluginUser.h"
#include <mutex> #include <mutex>
#include <shared_mutex>
#include <IceUtil/Optional.h> #include <IceUtil/Optional.h>
...@@ -255,9 +254,9 @@ namespace armarx ...@@ -255,9 +254,9 @@ namespace armarx
const skills::manager::dto::FluxioSkill& skill, const skills::manager::dto::FluxioSkill& skill,
const Ice::Current& current) const Ice::Current& current)
{ {
std::shared_lock skillsLock(this->plugin->fluxioDC.skillsMutex); std::scoped_lock l(this->plugin->fluxioDC.skillsMutex,
std::shared_lock profilesLock(this->plugin->fluxioDC.profilesMutex); this->plugin->fluxioDC.profilesMutex,
std::shared_lock providersLock(this->plugin->fluxioDC.providersMutex); this->plugin->fluxioDC.providersMutex);
auto& skillsMap = this->plugin->fluxioDC.skills; auto& skillsMap = this->plugin->fluxioDC.skills;
auto& providersMap = this->plugin->fluxioDC.providers; auto& providersMap = this->plugin->fluxioDC.providers;
auto& profilesMap = this->plugin->fluxioDC.profiles; auto& profilesMap = this->plugin->fluxioDC.profiles;
...@@ -268,14 +267,8 @@ namespace armarx ...@@ -268,14 +267,8 @@ namespace armarx
{ {
ARMARX_WARNING << "SkillManagerComponentPluginUser::updateSkill: Skill with id " ARMARX_WARNING << "SkillManagerComponentPluginUser::updateSkill: Skill with id "
<< skill.id << " not found"; << skill.id << " not found";
skillsLock.unlock();
profilesLock.unlock();
providersLock.unlock();
return false; return false;
} }
skillsLock.unlock();
profilesLock.unlock();
providersLock.unlock();
// Check if the user has the mutex for the skill // Check if the user has the mutex for the skill
if (!this->plugin->getSkillMutex(skill.id, userId)) if (!this->plugin->getSkillMutex(skill.id, userId))
...@@ -285,15 +278,7 @@ namespace armarx ...@@ -285,15 +278,7 @@ namespace armarx
return false; return false;
} }
profilesLock.lock();
providersLock.lock();
std::unique_lock skillsLock_unique(this->plugin->fluxioDC.skillsMutex);
const bool ret = s->second.updateFromIce(skill, providersMap, profilesMap, skillsMap); const bool ret = s->second.updateFromIce(skill, providersMap, profilesMap, skillsMap);
skillsLock_unique.unlock();
profilesLock.unlock();
providersLock.unlock();
return ret; return ret;
} }
...@@ -387,11 +372,12 @@ namespace armarx ...@@ -387,11 +372,12 @@ namespace armarx
const skills::manager::dto::FluxioProfile& profile, const skills::manager::dto::FluxioProfile& profile,
const Ice::Current& current) const Ice::Current& current)
{ {
std::unique_lock profilesLock(this->plugin->fluxioDC.profilesMutex); std::unique_lock l(this->plugin->fluxioDC.profilesMutex);
auto& profilesMap = this->plugin->fluxioDC.profiles; auto& profilesMap = this->plugin->fluxioDC.profiles;
l.unlock();
auto ret = this->plugin->createProfile(skills::FluxioProfile::FromIce(profile, profilesMap)) auto ret = this->plugin->createProfile(skills::FluxioProfile::FromIce(profile, profilesMap))
.toManagerIce(); .toManagerIce();
profilesLock.unlock();
return ret; return ret;
} }
...@@ -400,10 +386,11 @@ namespace armarx ...@@ -400,10 +386,11 @@ namespace armarx
const skills::manager::dto::FluxioProfile& profile, const skills::manager::dto::FluxioProfile& profile,
const Ice::Current& current) const Ice::Current& current)
{ {
std::unique_lock profilesLock(this->plugin->fluxioDC.profilesMutex); std::unique_lock l(this->plugin->fluxioDC.profilesMutex);
auto& profilesMap = this->plugin->fluxioDC.profiles; auto& profilesMap = this->plugin->fluxioDC.profiles;
l.unlock();
this->plugin->updateProfile(skills::FluxioProfile::FromIce(profile, profilesMap)); this->plugin->updateProfile(skills::FluxioProfile::FromIce(profile, profilesMap));
profilesLock.unlock();
} }
skills::manager::dto::FluxioProviderList skills::manager::dto::FluxioProviderList
...@@ -483,16 +470,15 @@ namespace armarx ...@@ -483,16 +470,15 @@ namespace armarx
const skills::manager::dto::FluxioSkill& skill, const skills::manager::dto::FluxioSkill& skill,
const Ice::Current& current) const Ice::Current& current)
{ {
std::unique_lock skillsLock(this->plugin->fluxioDC.skillsMutex); std::unique_lock skillsLock(this->plugin->fluxioDC.skillsMutex, std::defer_lock);
std::shared_lock profilesLock(this->plugin->fluxioDC.profilesMutex); std::unique_lock profilesLock(this->plugin->fluxioDC.profilesMutex, std::defer_lock);
std::shared_lock providersLock(this->plugin->fluxioDC.providersMutex); std::unique_lock providersLock(this->plugin->fluxioDC.providersMutex, std::defer_lock);
std::lock(skillsLock, profilesLock, providersLock);
auto& skillsMap = this->plugin->fluxioDC.skills; auto& skillsMap = this->plugin->fluxioDC.skills;
auto& providersMap = this->plugin->fluxioDC.providers; auto& providersMap = this->plugin->fluxioDC.providers;
auto& profilesMap = this->plugin->fluxioDC.profiles; auto& profilesMap = this->plugin->fluxioDC.profiles;
auto skillBO = skills::FluxioSkill::FromIce(skill, providersMap, profilesMap, skillsMap); auto skillBO = skills::FluxioSkill::FromIce(skill, providersMap, profilesMap, skillsMap);
skillsLock.unlock();
profilesLock.unlock();
providersLock.unlock();
if (skillBO == nullptr) if (skillBO == nullptr)
{ {
...@@ -500,8 +486,11 @@ namespace armarx ...@@ -500,8 +486,11 @@ namespace armarx
return {}; return {};
} }
auto& skillReleased = *skillBO.release(); skillsLock.unlock();
profilesLock.unlock();
providersLock.unlock();
auto& skillReleased = *skillBO.release();
const auto s = const auto s =
this->plugin->addSkillToProvider(userId, providerId, std::move(skillReleased)); this->plugin->addSkillToProvider(userId, providerId, std::move(skillReleased));
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment