From 5ff47dd1b539eaf279587419295f1d085bf6cf16 Mon Sep 17 00:00:00 2001
From: Rainer Kartmann <rainer.kartmann@kit.edu>
Date: Fri, 16 Jul 2021 11:10:49 +0200
Subject: [PATCH] Use core segment mutex in object memory segments

---
 .../server/ObjectMemory/ObjectMemory.cpp      | 24 +++++---
 .../armem/server/ObjectMemory/ObjectMemory.h  |  1 +
 .../server/attachments/Segment.cpp            | 61 +++----------------
 .../server/attachments/Segment.h              | 28 ++-------
 .../armem_objects/server/class/Segment.cpp    | 34 ++++++++---
 .../armem_objects/server/class/Segment.h      |  6 +-
 .../armem_objects/server/instance/Segment.cpp | 18 ++++--
 .../armem_objects/server/instance/Segment.h   |  8 +--
 .../server/instance/SegmentAdapter.cpp        | 48 +++++++++------
 .../server/instance/SegmentAdapter.h          |  3 +-
 10 files changed, 105 insertions(+), 126 deletions(-)

diff --git a/source/RobotAPI/components/armem/server/ObjectMemory/ObjectMemory.cpp b/source/RobotAPI/components/armem/server/ObjectMemory/ObjectMemory.cpp
index 91ea5b234..c624379b8 100644
--- a/source/RobotAPI/components/armem/server/ObjectMemory/ObjectMemory.cpp
+++ b/source/RobotAPI/components/armem/server/ObjectMemory/ObjectMemory.cpp
@@ -59,22 +59,27 @@ namespace armarx::armem::server::obj
         return defs;
     }
 
+
     ObjectMemory::ObjectMemory() :
         server::ComponentPluginUser(),
-        instance::SegmentAdapter(server::ComponentPluginUser::iceMemory,
-                                 server::ComponentPluginUser::workingMemoryMutex),
-        classSegment(server::ComponentPluginUser::iceMemory,
-                     server::ComponentPluginUser::workingMemoryMutex),
-        attachmentSegment(server::ComponentPluginUser::iceMemory,
-                          server::ComponentPluginUser::workingMemoryMutex)
+        instance::SegmentAdapter(server::ComponentPluginUser::iceMemory),
+        classSegment(server::ComponentPluginUser::iceMemory),
+        attachmentSegment(server::ComponentPluginUser::iceMemory)
+    {
+    }
+
+
+    ObjectMemory::~ObjectMemory()
     {
     }
 
+
     std::string ObjectMemory::getDefaultName() const
     {
         return "ObjectMemory";
     }
 
+
     void ObjectMemory::onInitComponent()
     {
         workingMemory.name() = defaultMemoryName;
@@ -114,6 +119,7 @@ namespace armarx::armem::server::obj
         });
     }
 
+
     void ObjectMemory::onConnectComponent()
     {
         // onConnect can be called multiple times, but addRobot will fail if called more than once with the same ID
@@ -141,17 +147,17 @@ namespace armarx::armem::server::obj
             ArVizComponentPluginUser::getArvizClient()
         );
 
-        attachmentSegment.connect(
-            ArVizComponentPluginUser::getArvizClient()
-        );
+        attachmentSegment.connect();
 
         RemoteGui_startRunningTask();
     }
 
+
     void ObjectMemory::onDisconnectComponent()
     {
     }
 
+
     void ObjectMemory::onExitComponent()
     {
     }
diff --git a/source/RobotAPI/components/armem/server/ObjectMemory/ObjectMemory.h b/source/RobotAPI/components/armem/server/ObjectMemory/ObjectMemory.h
index f29b2cef9..5ef38a94b 100644
--- a/source/RobotAPI/components/armem/server/ObjectMemory/ObjectMemory.h
+++ b/source/RobotAPI/components/armem/server/ObjectMemory/ObjectMemory.h
@@ -81,6 +81,7 @@ namespace armarx::armem::server::obj
     public:
 
         ObjectMemory();
+        virtual ~ObjectMemory();
 
 
         /// @see armarx::ManagedIceObject::getDefaultName()
diff --git a/source/RobotAPI/libraries/armem_objects/server/attachments/Segment.cpp b/source/RobotAPI/libraries/armem_objects/server/attachments/Segment.cpp
index f2490c841..bb5d930da 100644
--- a/source/RobotAPI/libraries/armem_objects/server/attachments/Segment.cpp
+++ b/source/RobotAPI/libraries/armem_objects/server/attachments/Segment.cpp
@@ -4,6 +4,7 @@
 
 #include <ArmarXCore/core/time/TimeUtil.h>
 #include "ArmarXCore/core/logging/Logging.h"
+#include <ArmarXCore/core/application/properties/forward_declarations.h>
 
 #include "RobotAPI/libraries/armem/util/util.h"
 #include "RobotAPI/libraries/aron/common/aron_conversions.h"
@@ -23,9 +24,8 @@
 
 namespace armarx::armem::server::obj::attachments
 {
-    Segment::Segment(armem::server::MemoryToIceAdapter& memoryToIceAdapter, std::mutex& memoryMutex) :
-        iceMemory(memoryToIceAdapter),
-        memoryMutex(memoryMutex)
+    Segment::Segment(armem::server::MemoryToIceAdapter& memoryToIceAdapter) :
+        iceMemory(memoryToIceAdapter)
     {
         Logging::setTag("Attachments");
     }
@@ -34,7 +34,7 @@ namespace armarx::armem::server::obj::attachments
 
     void Segment::defineProperties(armarx::PropertyDefinitionsPtr defs, const std::string& prefix)
     {
-        defs->optional(p.coreClassSegmentName, prefix + "CoreSegmentName", "Name of the object instance core segment.");
+        defs->optional(p.coreSegmentName, prefix + "CoreSegmentName", "Name of the object instance core segment.");
         defs->optional(p.maxHistorySize, prefix + "MaxHistorySize", "Maximal size of object poses history (-1 for infinite).");
     }
 
@@ -42,20 +42,22 @@ namespace armarx::armem::server::obj::attachments
     {
         ARMARX_CHECK_NOT_NULL(iceMemory.workingMemory);
 
-        coreSegment = &iceMemory.workingMemory->addCoreSegment(p.coreClassSegmentName, arondto::Robot::toAronType());
+        coreSegment = &iceMemory.workingMemory->addCoreSegment(p.coreSegmentName, arondto::Robot::toAronType());
         coreSegment->setMaxHistorySize(p.maxHistorySize);
     }
 
-    void Segment::connect(viz::Client arviz)
+    void Segment::connect()
     {
-        // this->visu = std::make_unique<Visu>(arviz, *this);
     }
 
     std::vector<armarx::armem::attachment::ObjectAttachment> Segment::getAttachments(const armem::Time& timestamp) const
     {
+        ARMARX_CHECK_NOT_NULL(coreSegment);
+        std::scoped_lock(coreSegment->mutex());
+
         std::vector<armarx::armem::attachment::ObjectAttachment> attachments;
 
-        for (const auto& [_, provSeg] : iceMemory.workingMemory->getCoreSegment(p.coreClassSegmentName))
+        for (const auto& [_, provSeg] : *coreSegment)
         {
             for (const auto& [name, entity] :  provSeg.entities())
             {
@@ -80,47 +82,4 @@ namespace armarx::armem::server::obj::attachments
         return attachments;
     }
 
-
-    // void Segment::RemoteGui::setup(const Segment& data)
-    // {
-    //     using namespace armarx::RemoteGui::Client;
-
-    //     maxHistorySize.setValue(std::max(1, int(data.p.maxHistorySize)));
-    //     maxHistorySize.setRange(1, 1e6);
-    //     infiniteHistory.setValue(data.p.maxHistorySize == -1);
-    //     discardSnapshotsWhileAttached.setValue(data.p.discardSnapshotsWhileAttached);
-
-    //     GridLayout grid;
-    //     int row = 0;
-    //     grid.add(Label("Max History Size"), {row, 0}).add(maxHistorySize, {row, 1});
-    //     row++;
-    //     grid.add(Label("Infinite History Size"), {row, 0}).add(infiniteHistory, {row, 1});
-    //     row++;
-    //     grid.add(Label("Discard Snapshots while Attached"), {row, 0}).add(discardSnapshotsWhileAttached, {row, 1});
-    //     row++;
-
-    //     group.setLabel("Data");
-    //     group.addChild(grid);
-    // }
-
-    // void Segment::RemoteGui::update(Segment& data)
-    // {
-    //     if (infiniteHistory.hasValueChanged() || maxHistorySize.hasValueChanged()
-    //         || discardSnapshotsWhileAttached.hasValueChanged())
-    //     {
-    //         std::scoped_lock lock(data.memoryMutex);
-
-    //         if (infiniteHistory.hasValueChanged() || maxHistorySize.hasValueChanged())
-    //         {
-    //             data.p.maxHistorySize = infiniteHistory.getValue() ? -1 : maxHistorySize.getValue();
-    //             if (data.coreSegment)
-    //             {
-    //                 data.coreSegment->setMaxHistorySize(long(data.p.maxHistorySize));
-    //             }
-    //         }
-
-    //         data.p.discardSnapshotsWhileAttached = discardSnapshotsWhileAttached.getValue();
-    //     }
-    // }
-
 }  // namespace armarx::armem::server::obj::attachments
diff --git a/source/RobotAPI/libraries/armem_objects/server/attachments/Segment.h b/source/RobotAPI/libraries/armem_objects/server/attachments/Segment.h
index 3817bc22a..0b9302d93 100644
--- a/source/RobotAPI/libraries/armem_objects/server/attachments/Segment.h
+++ b/source/RobotAPI/libraries/armem_objects/server/attachments/Segment.h
@@ -27,7 +27,7 @@
 #include <unordered_map>
 
 #include <ArmarXCore/core/logging/Logging.h>
-#include "ArmarXCore/core/application/properties/PropertyDefinitionContainer.h"
+#include <ArmarXCore/core/application/properties/forward_declarations.h>
 
 // #include "ArmarXGui/libraries/RemoteGui/Client/Widgets.h"
 
@@ -37,6 +37,7 @@
 #include "RobotAPI/libraries/armem/core/Time.h"
 #include "RobotAPI/libraries/armem_objects/types.h"
 
+
 namespace armarx::armem
 {
     namespace server
@@ -59,16 +60,14 @@ namespace armarx::armem::server::obj::attachments
     class Segment : public armarx::Logging
     {
     public:
-        Segment(server::MemoryToIceAdapter& iceMemory,
-                std::mutex& memoryMutex);
 
+        Segment(server::MemoryToIceAdapter& iceMemory);
         virtual ~Segment();
 
-        void connect(viz::Client arviz);
-
         void defineProperties(armarx::PropertyDefinitionsPtr defs, const std::string& prefix = "");
 
         void init();
+        void connect();
 
         std::vector<armarx::armem::attachment::ObjectAttachment> getAttachments(const armem::Time& timestamp) const;
 
@@ -77,31 +76,14 @@ namespace armarx::armem::server::obj::attachments
 
         server::MemoryToIceAdapter& iceMemory;
         wm::CoreSegment* coreSegment = nullptr;
-        std::mutex& memoryMutex;
 
         struct Properties
         {
-            std::string coreClassSegmentName = "Attachments";
+            std::string coreSegmentName = "Attachments";
             int64_t maxHistorySize = -1;
         };
         Properties p;
 
-        // std::unique_ptr<Visu> visu;
-
-    public:
-
-        // struct RemoteGui
-        // {
-        //     armarx::RemoteGui::Client::GroupBox group;
-
-        //     armarx::RemoteGui::Client::IntSpinBox maxHistorySize;
-        //     armarx::RemoteGui::Client::CheckBox infiniteHistory;
-        //     armarx::RemoteGui::Client::CheckBox discardSnapshotsWhileAttached;
-
-        //     void setup(const Segment& data);
-        //     void update(Segment& data);
-        // };
-
     };
 
 }  // namespace armarx::armem::server::obj::attachments
diff --git a/source/RobotAPI/libraries/armem_objects/server/class/Segment.cpp b/source/RobotAPI/libraries/armem_objects/server/class/Segment.cpp
index 3e6ecfed3..49c9b6dd8 100644
--- a/source/RobotAPI/libraries/armem_objects/server/class/Segment.cpp
+++ b/source/RobotAPI/libraries/armem_objects/server/class/Segment.cpp
@@ -19,13 +19,13 @@
 namespace armarx::armem::server::obj::clazz
 {
 
-    Segment::Segment(armem::server::MemoryToIceAdapter& memoryToIceAdapter, std::mutex& memoryMutex) :
-        iceMemory(memoryToIceAdapter),
-        memoryMutex(memoryMutex)
+    Segment::Segment(armem::server::MemoryToIceAdapter& memoryToIceAdapter) :
+        iceMemory(memoryToIceAdapter)
     {
         Logging::setTag("ClassSegment");
     }
 
+
     void Segment::defineProperties(armarx::PropertyDefinitionsPtr defs, const std::string& prefix)
     {
         defs->optional(p.coreSegmentName, prefix + "CoreSegmentName", "Name of the object clazz core segment.");
@@ -38,6 +38,7 @@ namespace armarx::armem::server::obj::clazz
         floorVis.defineProperties(defs, prefix + "Floor.");
     }
 
+
     void Segment::init()
     {
         ARMARX_CHECK_NOT_NULL(iceMemory.workingMemory);
@@ -51,6 +52,7 @@ namespace armarx::armem::server::obj::clazz
         }
     }
 
+
     void Segment::connect(viz::Client arviz)
     {
         this->arviz = arviz;
@@ -60,17 +62,26 @@ namespace armarx::armem::server::obj::clazz
     }
 
 
+    std::mutex& Segment::mutex() const
+    {
+        ARMARX_CHECK_NOT_NULL(coreSegment);
+        return coreSegment->mutex();
+    }
+
+
     void Segment::loadByObjectFinder(const std::string& objectsPackage)
     {
         loadByObjectFinder(ObjectFinder(objectsPackage));
     }
 
+
     void Segment::loadByObjectFinder(const ObjectFinder& finder)
     {
         this->objectFinder = finder;
         loadByObjectFinder();
     }
 
+
     void Segment::loadByObjectFinder()
     {
         const Time now = TimeUtil::GetTime();
@@ -106,6 +117,7 @@ namespace armarx::armem::server::obj::clazz
         iceMemory.commit(commit);
     }
 
+
     void Segment::visualizeClass(const MemoryID& entityID, bool showAABB, bool showOOBB)
     {
         const Eigen::Matrix4f pose = Eigen::Matrix4f::Identity();
@@ -164,6 +176,7 @@ namespace armarx::armem::server::obj::clazz
         arviz.commit(layerObject, layerOrigin, layerAABB, layerOOBB);
     }
 
+
     arondto::ObjectClass Segment::objectClassFromInfo(const ObjectInfo& info)
     {
         namespace fs = std::filesystem;
@@ -173,8 +186,8 @@ namespace armarx::armem::server::obj::clazz
         toAron(data.id, info.id());
 
         auto setPathIfExists = [](
-                armarx::arondto::PackagePath & aron,
-                const PackageFileLocation & location)
+                                   armarx::arondto::PackagePath & aron,
+                                   const PackageFileLocation & location)
         {
             if (fs::is_regular_file(location.absolutePath))
             {
@@ -223,12 +236,14 @@ namespace armarx::armem::server::obj::clazz
         group.addChildren({layout, VSpacer()});
     }
 
+
     void Segment::RemoteGui::update(Segment& segment)
     {
         data.update(segment);
         visu.update(segment);
     }
 
+
     void Segment::RemoteGui::Data::setup(const Segment& segment)
     {
         using namespace armarx::RemoteGui::Client;
@@ -253,17 +268,18 @@ namespace armarx::armem::server::obj::clazz
         group.addChild(grid);
     }
 
+
     void Segment::RemoteGui::Data::update(Segment& segment)
     {
         if (reloadButton.wasClicked())
         {
-            std::scoped_lock lock(segment.memoryMutex);
+            std::scoped_lock lock(segment.mutex());
             segment.loadByObjectFinder();
             rebuild = true;
         }
         if (infiniteHistory.hasValueChanged() || maxHistorySize.hasValueChanged())
         {
-            std::scoped_lock lock(segment.memoryMutex);
+            std::scoped_lock lock(segment.mutex());
             segment.p.maxHistorySize = infiniteHistory.getValue() ? -1 : maxHistorySize.getValue();
             if (segment.coreSegment)
             {
@@ -273,7 +289,6 @@ namespace armarx::armem::server::obj::clazz
     }
 
 
-
     void Segment::RemoteGui::Visu::setup(const Segment& segment)
     {
         using namespace armarx::RemoteGui::Client;
@@ -308,6 +323,7 @@ namespace armarx::armem::server::obj::clazz
         group.addChild(grid);
     }
 
+
     void Segment::RemoteGui::Visu::update(Segment& segment)
     {
         if (showButton.wasClicked())
@@ -315,7 +331,7 @@ namespace armarx::armem::server::obj::clazz
             const size_t index = static_cast<size_t>(showComboBox.getIndex());
             if (/*index >= 0 &&*/ index < showOptionsIndex.size())
             {
-                std::scoped_lock lock(segment.memoryMutex);
+                std::scoped_lock lock(segment.mutex());
                 segment.visualizeClass(showOptionsIndex.at(index));
             }
         }
diff --git a/source/RobotAPI/libraries/armem_objects/server/class/Segment.h b/source/RobotAPI/libraries/armem_objects/server/class/Segment.h
index 88eaedbef..03dce0e9a 100644
--- a/source/RobotAPI/libraries/armem_objects/server/class/Segment.h
+++ b/source/RobotAPI/libraries/armem_objects/server/class/Segment.h
@@ -25,14 +25,15 @@ namespace armarx::armem::server::obj::clazz
     {
     public:
 
-        Segment(armem::server::MemoryToIceAdapter& iceMemory,
-                std::mutex& memoryMutex);
+        Segment(armem::server::MemoryToIceAdapter& iceMemory);
 
 
         void defineProperties(armarx::PropertyDefinitionsPtr defs, const std::string& prefix = "");
         void init();
         void connect(viz::Client arviz);
 
+        std::mutex& mutex() const;
+
         void loadByObjectFinder(const std::string& objectsPackage);
         void loadByObjectFinder(const ObjectFinder& finder);
         void loadByObjectFinder();
@@ -47,7 +48,6 @@ namespace armarx::armem::server::obj::clazz
 
         armem::server::MemoryToIceAdapter& iceMemory;
         armem::wm::CoreSegment* coreSegment = nullptr;
-        std::mutex& memoryMutex;
 
         ObjectFinder objectFinder;
 
diff --git a/source/RobotAPI/libraries/armem_objects/server/instance/Segment.cpp b/source/RobotAPI/libraries/armem_objects/server/instance/Segment.cpp
index db706075c..95611ed7a 100644
--- a/source/RobotAPI/libraries/armem_objects/server/instance/Segment.cpp
+++ b/source/RobotAPI/libraries/armem_objects/server/instance/Segment.cpp
@@ -42,9 +42,8 @@
 namespace armarx::armem::server::obj::instance
 {
 
-    Segment::Segment(armem::server::MemoryToIceAdapter& memoryToIceAdapter, std::mutex& memoryMutex) :
-        iceMemory(memoryToIceAdapter),
-        memoryMutex(memoryMutex)
+    Segment::Segment(armem::server::MemoryToIceAdapter& memoryToIceAdapter) :
+        iceMemory(memoryToIceAdapter)
     {
         Logging::setTag("InstanceSegment");
 
@@ -123,6 +122,13 @@ namespace armarx::armem::server::obj::instance
     }
 
 
+    std::mutex& Segment::mutex() const
+    {
+        ARMARX_CHECK_NOT_NULL(coreSegment);
+        return coreSegment->mutex();
+    }
+
+
     Segment::CommitStats Segment::commitObjectPoses(
         const std::string& providerName,
         const objpose::data::ProvidedObjectPoseSeq& providedPoses,
@@ -973,7 +979,7 @@ namespace armarx::armem::server::obj::instance
 
                 if (lockMemory)
                 {
-                    std::scoped_lock lock(memoryMutex);
+                    std::scoped_lock lock(mutex());
                     commitSceneSnapshot(snapshot.value(), filename.string());
                 }
                 else
@@ -1038,7 +1044,7 @@ namespace armarx::armem::server::obj::instance
         {
             armem::obj::SceneSnapshot scene;
             {
-                std::scoped_lock lock(data.memoryMutex);
+                std::scoped_lock lock(data.mutex());
                 scene = data.getSceneSnapshot();
             }
             data.storeScene(storeLoadLine.getValue(), scene);
@@ -1047,7 +1053,7 @@ namespace armarx::armem::server::obj::instance
         if (infiniteHistory.hasValueChanged() || maxHistorySize.hasValueChanged()
             || discardSnapshotsWhileAttached.hasValueChanged())
         {
-            std::scoped_lock lock(data.memoryMutex);
+            std::scoped_lock lock(data.mutex());
 
             if (infiniteHistory.hasValueChanged() || maxHistorySize.hasValueChanged())
             {
diff --git a/source/RobotAPI/libraries/armem_objects/server/instance/Segment.h b/source/RobotAPI/libraries/armem_objects/server/instance/Segment.h
index 3ec6a2f22..378cf02da 100644
--- a/source/RobotAPI/libraries/armem_objects/server/instance/Segment.h
+++ b/source/RobotAPI/libraries/armem_objects/server/instance/Segment.h
@@ -50,16 +50,15 @@ namespace armarx::armem::server::obj::instance
 
     public:
 
-        Segment(server::MemoryToIceAdapter& iceMemory,
-                std::mutex& memoryMutex);
+        Segment(server::MemoryToIceAdapter& iceMemory);
 
 
         void defineProperties(armarx::PropertyDefinitionsPtr defs, const std::string& prefix = "");
-
         void init();
-
         void connect(viz::Client arviz);
 
+        std::mutex& mutex() const;
+
 
 
         CommitStats commitObjectPoses(
@@ -181,7 +180,6 @@ namespace armarx::armem::server::obj::instance
 
         server::MemoryToIceAdapter& iceMemory;
         wm::CoreSegment* coreSegment = nullptr;
-        std::mutex& memoryMutex;
 
 
         struct Properties
diff --git a/source/RobotAPI/libraries/armem_objects/server/instance/SegmentAdapter.cpp b/source/RobotAPI/libraries/armem_objects/server/instance/SegmentAdapter.cpp
index e0577877f..7cd8b1202 100644
--- a/source/RobotAPI/libraries/armem_objects/server/instance/SegmentAdapter.cpp
+++ b/source/RobotAPI/libraries/armem_objects/server/instance/SegmentAdapter.cpp
@@ -37,17 +37,18 @@
 namespace armarx::armem::server::obj::instance
 {
 
-    SegmentAdapter::SegmentAdapter(MemoryToIceAdapter& iceMemory, std::mutex& memoryMutex) :
-        segment(iceMemory, memoryMutex),
-        memoryMutex(memoryMutex)
+    SegmentAdapter::SegmentAdapter(MemoryToIceAdapter& iceMemory) :
+        segment(iceMemory)
     {
     }
 
+
     std::string SegmentAdapter::getName() const
     {
         return Logging::tag.tagName;
     }
 
+
     void SegmentAdapter::defineProperties(armarx::PropertyDefinitionsPtr defs, const std::string& prefix)
     {
         calibration.defineProperties(defs, prefix + "calibration.");
@@ -56,6 +57,7 @@ namespace armarx::armem::server::obj::instance
         visu.defineProperties(defs, prefix + "visu.");
     }
 
+
     void SegmentAdapter::init()
     {
         segment.setTag(getName());
@@ -66,6 +68,7 @@ namespace armarx::armem::server::obj::instance
         segment.init();
     }
 
+
     void SegmentAdapter::connect(
         RobotStateComponentInterfacePrx robotStateComponent,
         VirtualRobot::RobotPtr robot,
@@ -97,6 +100,7 @@ namespace armarx::armem::server::obj::instance
         segment.connect(arviz);
     }
 
+
     void SegmentAdapter::reportProviderAvailable(const std::string& providerName, const objpose::ProviderInfo& info, const Ice::Current&)
     {
         updateProviderInfo(providerName, info);
@@ -120,7 +124,7 @@ namespace armarx::armem::server::obj::instance
             return;
         }
         {
-            std::scoped_lock lock(memoryMutex);
+            std::scoped_lock lock(segment.mutex());
             std::stringstream ss;
             for (const auto& id : info.supportedObjects)
             {
@@ -161,7 +165,7 @@ namespace armarx::armem::server::obj::instance
         }
 
         {
-            std::scoped_lock lock(memoryMutex);
+            std::scoped_lock lock(segment.mutex());
             RemoteRobot::synchronizeLocalClone(segment.robot, segment.robotStateComponent);
 
             if (segment.robot->hasRobotNode(calibration.robotNode))
@@ -215,7 +219,7 @@ namespace armarx::armem::server::obj::instance
         TIMING_START(tGetObjectPoses);
 
         TIMING_START(tGetObjectPosesLock);
-        std::scoped_lock lock(memoryMutex);
+        std::scoped_lock lock(segment.mutex());
         TIMING_END_STREAM(tGetObjectPosesLock, ARMARX_VERBOSE);
 
         const IceUtil::Time now = TimeUtil::GetTime();
@@ -240,7 +244,7 @@ namespace armarx::armem::server::obj::instance
         TIMING_START(GetObjectPoses);
 
         TIMING_START(GetObjectPosesLock);
-        std::scoped_lock lock(memoryMutex);
+        std::scoped_lock lock(segment.mutex());
         TIMING_END_STREAM(GetObjectPosesLock, ARMARX_VERBOSE);
 
         const IceUtil::Time now = TimeUtil::GetTime();
@@ -292,7 +296,7 @@ namespace armarx::armem::server::obj::instance
         }
         else
         {
-            std::scoped_lock lock(memoryMutex);
+            std::scoped_lock lock(segment.mutex());
             for (const auto& objectID : input.request.objectIDs)
             {
                 bool found = true;
@@ -336,27 +340,31 @@ namespace armarx::armem::server::obj::instance
         return output;
     }
 
+
     objpose::ProviderInfoMap SegmentAdapter::getAvailableProvidersInfo(const Ice::Current&)
     {
-        std::scoped_lock lock(memoryMutex);
+        std::scoped_lock lock(segment.mutex());
         return segment.providers;
     }
 
+
     Ice::StringSeq SegmentAdapter::getAvailableProviderNames(const Ice::Current&)
     {
-        std::scoped_lock lock(memoryMutex);
+        std::scoped_lock lock(segment.mutex());
         return simox::alg::get_keys(segment.providers);
     }
 
+
     objpose::ProviderInfo SegmentAdapter::getProviderInfo(const std::string& providerName, const Ice::Current&)
     {
-        std::scoped_lock lock(memoryMutex);
+        std::scoped_lock lock(segment.mutex());
         return segment.getProviderInfo(providerName);
     }
 
+
     bool SegmentAdapter::hasProvider(const std::string& providerName, const Ice::Current&)
     {
-        std::scoped_lock lock(memoryMutex);
+        std::scoped_lock lock(segment.mutex());
         return segment.providers.count(providerName) > 0;
     }
 
@@ -364,28 +372,30 @@ namespace armarx::armem::server::obj::instance
     objpose::AttachObjectToRobotNodeOutput SegmentAdapter::attachObjectToRobotNode(
         const objpose::AttachObjectToRobotNodeInput& input, const Ice::Current&)
     {
-        std::scoped_lock lock(memoryMutex);
+        std::scoped_lock lock(segment.mutex());
         return segment.attachObjectToRobotNode(input);
     }
 
+
     objpose::DetachObjectFromRobotNodeOutput SegmentAdapter::detachObjectFromRobotNode(
         const objpose::DetachObjectFromRobotNodeInput& input, const Ice::Current&)
     {
-        std::scoped_lock lock(memoryMutex);
+        std::scoped_lock lock(segment.mutex());
         return segment.detachObjectFromRobotNode(input);
     }
 
+
     objpose::DetachAllObjectsFromRobotNodesOutput SegmentAdapter::detachAllObjectsFromRobotNodes(
         const objpose::DetachAllObjectsFromRobotNodesInput& input, const Ice::Current&)
     {
-        std::scoped_lock lock(memoryMutex);
+        std::scoped_lock lock(segment.mutex());
         return segment.detachAllObjectsFromRobotNodes(input);
     }
 
 
     objpose::AgentFramesSeq SegmentAdapter::getAttachableFrames(const Ice::Current&)
     {
-        std::scoped_lock lock(memoryMutex);
+        std::scoped_lock lock(segment.mutex());
 
         objpose::AgentFramesSeq output;
         std::vector<VirtualRobot::RobotPtr> agents = { segment.robot };
@@ -398,6 +408,7 @@ namespace armarx::armem::server::obj::instance
         return output;
     }
 
+
     objpose::SignalHeadMovementOutput
     SegmentAdapter::signalHeadMovement(const objpose::SignalHeadMovementInput& input, const Ice::Current&)
     {
@@ -423,7 +434,7 @@ namespace armarx::armem::server::obj::instance
                     objpose::ObjectPoseMap objectPoses;
                     visu.minConfidence = -1;
                     {
-                        std::scoped_lock lock(memoryMutex);
+                        std::scoped_lock lock(segment.mutex());
 
                         const IceUtil::Time now = TimeUtil::GetTime();
 
@@ -493,6 +504,7 @@ namespace armarx::armem::server::obj::instance
         group.addChild(layout);
     }
 
+
     void SegmentAdapter::RemoteGui::update(SegmentAdapter& adapter)
     {
         // Non-atomic variables need to be guarded by a mutex if accessed by multiple threads
@@ -502,7 +514,7 @@ namespace armarx::armem::server::obj::instance
         }
         this->segment.update(adapter.segment);
         {
-            std::scoped_lock lock(adapter.memoryMutex);
+            std::scoped_lock lock(adapter.segment.mutex());
             this->decay.update(adapter.segment.decay);
         }
         {
diff --git a/source/RobotAPI/libraries/armem_objects/server/instance/SegmentAdapter.h b/source/RobotAPI/libraries/armem_objects/server/instance/SegmentAdapter.h
index a1e356e53..353f2e064 100644
--- a/source/RobotAPI/libraries/armem_objects/server/instance/SegmentAdapter.h
+++ b/source/RobotAPI/libraries/armem_objects/server/instance/SegmentAdapter.h
@@ -55,7 +55,7 @@ namespace armarx::armem::server::obj::instance
     {
     public:
 
-        SegmentAdapter(MemoryToIceAdapter& iceMemory, std::mutex& memoryMutex);
+        SegmentAdapter(MemoryToIceAdapter& iceMemory);
 
         std::string getName() const;
         void defineProperties(armarx::PropertyDefinitionsPtr defs, const std::string& prefix = "");
@@ -127,7 +127,6 @@ namespace armarx::armem::server::obj::instance
         DebugObserverInterfacePrx debugObserver;
 
         instance::Segment segment;
-        std::mutex& memoryMutex;
 
         instance::RobotHeadMovement robotHead;
         std::mutex robotHeadMutex;
-- 
GitLab