Browse Source

Protect public access to Modificators with another mutex.

Tomasz Zieliński 2 years ago
parent
commit
966a24d27e

+ 4 - 4
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<boost::shared_mutex>;
+
 private:
 	virtual void process() = 0;
 
 	std::string name;
-	//bool started = false;
 
 	std::list<Modificator*> preceeders; //must be ordered container
 
-	mutable boost::shared_mutex mx;
-	using Lock = boost::unique_lock<boost::shared_mutex>;
+	mutable boost::shared_mutex mx; //Used only for task scheduling
 
 	void dump();
 };

+ 7 - 0
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<CGObjectInstance*> ObjectManager::getMines() const
 {
+	Lock lock(externalAccessMutex);
 	std::vector<CGObjectInstance*> mines;
 
 	for(auto * object : objects)

+ 8 - 0
lib/rmg/QuestArtifactPlacer.cpp

@@ -33,22 +33,26 @@ void QuestArtifactPlacer::init()
 
 void QuestArtifactPlacer::addQuestArtZone(std::shared_ptr<Zone> 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<CGObjectInstance*> 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);
 }

+ 3 - 0
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());
 

+ 4 - 0
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;
 }
 

+ 2 - 0
lib/rmg/WaterProxy.cpp

@@ -90,11 +90,13 @@ void WaterProxy::init()
 
 const std::vector<WaterProxy::Lake> & 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))
 	{