From 966a24d27eeed32d41a8ddf2bcc2f1c85d2ad5b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Zieli=C5=84ski?= Date: Sun, 7 May 2023 08:24:08 +0200 Subject: [PATCH] Protect public access to Modificators with another mutex. --- lib/rmg/Modificator.h | 8 ++++---- lib/rmg/ObjectManager.cpp | 7 +++++++ lib/rmg/QuestArtifactPlacer.cpp | 8 ++++++++ lib/rmg/RoadPlacer.cpp | 3 +++ lib/rmg/TreasurePlacer.cpp | 4 ++++ lib/rmg/WaterProxy.cpp | 2 ++ 6 files changed, 28 insertions(+), 4 deletions(-) diff --git a/lib/rmg/Modificator.h b/lib/rmg/Modificator.h index 7f5652ae0..f5abed8da 100644 --- a/lib/rmg/Modificator.h +++ b/lib/rmg/Modificator.h @@ -62,17 +62,17 @@ protected: bool finished = false; - //bool wasStarted() const; + mutable boost::shared_mutex externalAccessMutex; //Used to communicate between Modificators + using Lock = boost::unique_lock; + private: virtual void process() = 0; std::string name; - //bool started = false; std::list preceeders; //must be ordered container - mutable boost::shared_mutex mx; - using Lock = boost::unique_lock; + mutable boost::shared_mutex mx; //Used only for task scheduling void dump(); }; diff --git a/lib/rmg/ObjectManager.cpp b/lib/rmg/ObjectManager.cpp index 18cda16be..a30e2cdba 100644 --- a/lib/rmg/ObjectManager.cpp +++ b/lib/rmg/ObjectManager.cpp @@ -43,6 +43,7 @@ void ObjectManager::init() void ObjectManager::createDistancesPriorityQueue() { + Lock lock(externalAccessMutex); tilesByDistance.clear(); for(const auto & tile : zone.areaPossible().getTilesVector()) { @@ -52,21 +53,25 @@ void ObjectManager::createDistancesPriorityQueue() void ObjectManager::addRequiredObject(CGObjectInstance * obj, si32 strength) { + Lock lock(externalAccessMutex); requiredObjects.emplace_back(obj, strength); } void ObjectManager::addCloseObject(CGObjectInstance * obj, si32 strength) { + Lock lock(externalAccessMutex); closeObjects.emplace_back(obj, strength); } void ObjectManager::addNearbyObject(CGObjectInstance * obj, CGObjectInstance * nearbyTarget) { + Lock lock(externalAccessMutex); nearbyObjects.emplace_back(obj, nearbyTarget); } void ObjectManager::updateDistances(const rmg::Object & obj) { + Lock lock(externalAccessMutex); tilesByDistance.clear(); for (auto tile : zone.areaPossible().getTiles()) //don't need to mark distance for not possible tiles { @@ -78,11 +83,13 @@ void ObjectManager::updateDistances(const rmg::Object & obj) const rmg::Area & ObjectManager::getVisitableArea() const { + Lock lock(externalAccessMutex); return objectsVisitableArea; } std::vector ObjectManager::getMines() const { + Lock lock(externalAccessMutex); std::vector mines; for(auto * object : objects) diff --git a/lib/rmg/QuestArtifactPlacer.cpp b/lib/rmg/QuestArtifactPlacer.cpp index 874e273c8..9e5e0846d 100644 --- a/lib/rmg/QuestArtifactPlacer.cpp +++ b/lib/rmg/QuestArtifactPlacer.cpp @@ -33,22 +33,26 @@ void QuestArtifactPlacer::init() void QuestArtifactPlacer::addQuestArtZone(std::shared_ptr otherZone) { + Lock lock(externalAccessMutex); questArtZones.push_back(otherZone); } void QuestArtifactPlacer::addQuestArtifact(const ArtifactID& id) { + Lock lock(externalAccessMutex); logGlobal->info("Need to place quest artifact artifact %s", VLC->artifacts()->getById(id)->getNameTranslated()); questArtifactsToPlace.emplace_back(id); } void QuestArtifactPlacer::rememberPotentialArtifactToReplace(CGObjectInstance* obj) { + Lock lock(externalAccessMutex); artifactsToReplace.push_back(obj); } std::vector QuestArtifactPlacer::getPossibleArtifactsToReplace() const { + Lock lock(externalAccessMutex); return artifactsToReplace; } @@ -109,16 +113,19 @@ void QuestArtifactPlacer::placeQuestArtifacts(CRandomGenerator * rand) void QuestArtifactPlacer::dropReplacedArtifact(CGObjectInstance* obj) { + Lock lock(externalAccessMutex); boost::remove(artifactsToReplace, obj); } size_t QuestArtifactPlacer::getMaxQuestArtifactCount() const { + Lock lock(externalAccessMutex); return questArtifacts.size(); } ArtifactID QuestArtifactPlacer::drawRandomArtifact() { + Lock lock(externalAccessMutex); if (!questArtifacts.empty()) { ArtifactID ret = questArtifacts.back(); @@ -134,5 +141,6 @@ ArtifactID QuestArtifactPlacer::drawRandomArtifact() void QuestArtifactPlacer::addRandomArtifact(ArtifactID artid) { + Lock lock(externalAccessMutex); questArtifacts.push_back(artid); } diff --git a/lib/rmg/RoadPlacer.cpp b/lib/rmg/RoadPlacer.cpp index 19d9bca5d..4e7a0f27d 100644 --- a/lib/rmg/RoadPlacer.cpp +++ b/lib/rmg/RoadPlacer.cpp @@ -76,6 +76,7 @@ void RoadPlacer::drawRoads(bool secondary) || (!secondary && generator.getConfig().defaultRoadType.empty())) return; + Lock lock(externalAccessMutex); zone.areaPossible().subtract(roads); zone.freePaths().unite(roads); map.getEditManager()->getTerrainSelection().setSelection(roads.getTilesVector()); @@ -87,6 +88,7 @@ void RoadPlacer::drawRoads(bool secondary) void RoadPlacer::addRoadNode(const int3& node) { + Lock lock(externalAccessMutex); roadNodes.insert(node); } @@ -111,6 +113,7 @@ void RoadPlacer::connectRoads() return; //take any tile from road nodes as destination zone for all other road nodes + Lock lock(externalAccessMutex); if(roads.empty()) roads.add(*roadNodes.begin()); diff --git a/lib/rmg/TreasurePlacer.cpp b/lib/rmg/TreasurePlacer.cpp index a97d90401..433bf655e 100644 --- a/lib/rmg/TreasurePlacer.cpp +++ b/lib/rmg/TreasurePlacer.cpp @@ -45,6 +45,7 @@ void TreasurePlacer::init() void TreasurePlacer::addObjectToRandomPool(const ObjectInfo& oi) { + Lock lock(externalAccessMutex); possibleObjects.push_back(oi); } @@ -525,16 +526,19 @@ void TreasurePlacer::addAllPossibleObjects() size_t TreasurePlacer::getPossibleObjectsSize() const { + Lock lock(externalAccessMutex); return possibleObjects.size(); } void TreasurePlacer::setMaxPrisons(size_t count) { + Lock lock(externalAccessMutex); maxPrisons = count; } size_t TreasurePlacer::getMaxPrisons() const { + Lock lock(externalAccessMutex); return maxPrisons; } diff --git a/lib/rmg/WaterProxy.cpp b/lib/rmg/WaterProxy.cpp index d8d133fff..c15fbc2e8 100644 --- a/lib/rmg/WaterProxy.cpp +++ b/lib/rmg/WaterProxy.cpp @@ -90,11 +90,13 @@ void WaterProxy::init() const std::vector & WaterProxy::getLakes() const { + Lock lock(externalAccessMutex); return lakes; } void WaterProxy::collectLakes() { + Lock lock(externalAccessMutex); int lakeId = 0; for(const auto & lake : connectedAreas(zone.getArea(), true)) {