Pārlūkot izejas kodu

Merge pull request #2627 from IvanSavenko/threading_cleanup

Threading cleanup
Ivan Savenko 2 gadi atpakaļ
vecāks
revīzija
a852236602
100 mainītis faili ar 145 papildinājumiem un 374 dzēšanām
  1. 11 9
      AI/Nullkiller/AIGateway.cpp
  2. 0 4
      AI/Nullkiller/AIUtility.cpp
  3. 4 2
      AI/Nullkiller/AIUtility.h
  4. 0 3
      AI/Nullkiller/Behaviors/BuildingBehavior.cpp
  5. 0 3
      AI/Nullkiller/Behaviors/BuyArmyBehavior.cpp
  6. 0 3
      AI/Nullkiller/Behaviors/CaptureObjectsBehavior.cpp
  7. 0 3
      AI/Nullkiller/Behaviors/ClusterBehavior.cpp
  8. 0 3
      AI/Nullkiller/Behaviors/DefenceBehavior.cpp
  9. 0 3
      AI/Nullkiller/Behaviors/GatherArmyBehavior.cpp
  10. 0 3
      AI/Nullkiller/Behaviors/RecruitHeroBehavior.cpp
  11. 0 3
      AI/Nullkiller/Behaviors/StartupBehavior.cpp
  12. 0 3
      AI/Nullkiller/Engine/DeepDecomposer.cpp
  13. 0 2
      AI/Nullkiller/Engine/FuzzyEngines.cpp
  14. 1 4
      AI/Nullkiller/Engine/Nullkiller.cpp
  15. 0 3
      AI/Nullkiller/Goals/AbstractGoal.cpp
  16. 0 3
      AI/Nullkiller/Goals/AdventureSpellCast.cpp
  17. 0 3
      AI/Nullkiller/Goals/BuildBoat.cpp
  18. 0 4
      AI/Nullkiller/Goals/BuildThis.cpp
  19. 0 3
      AI/Nullkiller/Goals/BuyArmy.cpp
  20. 0 2
      AI/Nullkiller/Goals/CaptureObject.cpp
  21. 0 3
      AI/Nullkiller/Goals/CompleteQuest.cpp
  22. 0 3
      AI/Nullkiller/Goals/Composition.cpp
  23. 0 3
      AI/Nullkiller/Goals/DigAtTile.cpp
  24. 0 3
      AI/Nullkiller/Goals/DismissHero.cpp
  25. 0 3
      AI/Nullkiller/Goals/ExchangeSwapTownHeroes.cpp
  26. 0 3
      AI/Nullkiller/Goals/ExecuteHeroChain.cpp
  27. 0 3
      AI/Nullkiller/Goals/RecruitHero.cpp
  28. 0 3
      AI/Nullkiller/Goals/SaveResources.cpp
  29. 0 3
      AI/Nullkiller/Markers/ArmyUpgrade.cpp
  30. 0 3
      AI/Nullkiller/Markers/HeroExchange.cpp
  31. 0 3
      AI/Nullkiller/Markers/UnlockCluster.cpp
  32. 0 3
      AI/Nullkiller/Pathfinding/Actions/BattleAction.cpp
  33. 2 5
      AI/Nullkiller/Pathfinding/Actions/BoatActions.cpp
  34. 0 3
      AI/Nullkiller/Pathfinding/Actions/BuyArmyAction.cpp
  35. 0 3
      AI/Nullkiller/Pathfinding/Actions/QuestAction.cpp
  36. 1 4
      AI/Nullkiller/Pathfinding/Actions/TownPortalAction.cpp
  37. 1 1
      AI/StupidAI/StupidAI.cpp
  38. 0 4
      AI/VCAI/AIUtility.cpp
  39. 4 2
      AI/VCAI/AIUtility.h
  40. 0 3
      AI/VCAI/FuzzyEngines.cpp
  41. 1 4
      AI/VCAI/FuzzyHelper.cpp
  42. 2 0
      AI/VCAI/FuzzyHelper.h
  43. 0 4
      AI/VCAI/Goals/AbstractGoal.cpp
  44. 0 4
      AI/VCAI/Goals/AdventureSpellCast.cpp
  45. 0 5
      AI/VCAI/Goals/Build.cpp
  46. 0 4
      AI/VCAI/Goals/BuildBoat.cpp
  47. 0 5
      AI/VCAI/Goals/BuildThis.cpp
  48. 0 5
      AI/VCAI/Goals/BuyArmy.cpp
  49. 0 5
      AI/VCAI/Goals/ClearWayTo.cpp
  50. 0 5
      AI/VCAI/Goals/CollectRes.cpp
  51. 0 4
      AI/VCAI/Goals/CompleteQuest.cpp
  52. 0 5
      AI/VCAI/Goals/Conquer.cpp
  53. 0 5
      AI/VCAI/Goals/DigAtTile.cpp
  54. 2 6
      AI/VCAI/Goals/Explore.cpp
  55. 0 4
      AI/VCAI/Goals/FindObj.cpp
  56. 0 5
      AI/VCAI/Goals/GatherArmy.cpp
  57. 0 5
      AI/VCAI/Goals/GatherTroops.cpp
  58. 1 6
      AI/VCAI/Goals/GetArtOfType.cpp
  59. 0 5
      AI/VCAI/Goals/RecruitHero.cpp
  60. 0 4
      AI/VCAI/Goals/VisitHero.cpp
  61. 0 5
      AI/VCAI/Goals/VisitObj.cpp
  62. 0 5
      AI/VCAI/Goals/VisitTile.cpp
  63. 0 5
      AI/VCAI/Goals/Win.cpp
  64. 11 9
      AI/VCAI/VCAI.cpp
  65. 6 3
      Global.h
  66. 11 8
      client/CMT.cpp
  67. 4 4
      client/CMusicHandler.cpp
  68. 5 4
      client/CPlayerInterface.cpp
  69. 13 12
      client/CServerHandler.cpp
  70. 1 1
      client/CVideoHandler.cpp
  71. 2 0
      client/adventureMap/CInGameConsole.cpp
  72. 3 3
      client/battle/BattleInterface.cpp
  73. 1 1
      client/battle/BattleWindow.cpp
  74. 0 8
      client/eventsSDL/InputSourceKeyboard.cpp
  75. 6 20
      client/gui/CGuiHandler.cpp
  76. 0 2
      client/gui/CGuiHandler.h
  77. 4 3
      client/mainmenu/CMainMenu.cpp
  78. 1 1
      client/mapView/mapHandler.cpp
  79. 1 1
      client/windows/CSpellWindow.cpp
  80. 2 2
      lib/CConsoleHandler.cpp
  81. 2 7
      lib/CRandomGenerator.cpp
  82. 0 1
      lib/CRandomGenerator.h
  83. 5 3
      lib/CThreadHelper.cpp
  84. 4 4
      lib/CThreadHelper.h
  85. 1 1
      lib/logging/CLogger.cpp
  86. 1 1
      lib/mapObjects/CGCreature.cpp
  87. 1 1
      lib/mapObjects/CGHeroInstance.cpp
  88. 1 1
      lib/rmg/CMapGenerator.cpp
  89. 2 2
      lib/rmg/CRmgTemplate.cpp
  90. 2 2
      lib/rmg/RmgMap.cpp
  91. 6 6
      lib/rmg/RmgObject.cpp
  92. 1 1
      lib/rmg/modificators/Modificator.cpp
  93. 1 1
      lib/rmg/modificators/RiverPlacer.cpp
  94. 2 2
      lib/rmg/threadpool/ThreadPool.h
  95. 2 8
      server/CGameHandler.cpp
  96. 9 6
      server/CVCMIServer.cpp
  97. 0 7
      server/StdInc.h
  98. 0 2
      test/CMakeLists.txt
  99. 1 1
      test/JsonComparer.cpp
  100. 3 3
      test/map/MapComparer.cpp

+ 11 - 9
AI/Nullkiller/AIGateway.cpp

@@ -34,26 +34,26 @@ const float RETREAT_THRESHOLD = 0.3f;
 const double RETREAT_ABSOLUTE_THRESHOLD = 10000.;
 
 //one thread may be turn of AI and another will be handling a side effect for AI2
-boost::thread_specific_ptr<CCallback> cb;
-boost::thread_specific_ptr<AIGateway> ai;
+thread_local CCallback * cb = nullptr;
+thread_local AIGateway * ai = nullptr;
 
 //helper RAII to manage global ai/cb ptrs
 struct SetGlobalState
 {
 	SetGlobalState(AIGateway * AI)
 	{
-		assert(!ai.get());
-		assert(!cb.get());
+		assert(!ai);
+		assert(!cb);
 
-		ai.reset(AI);
-		cb.reset(AI->myCb.get());
+		ai = AI;
+		cb = AI->myCb.get();
 	}
 	~SetGlobalState()
 	{
 		//TODO: how to handle rm? shouldn't be called after ai is destroyed, hopefully
 		//TODO: to ensure that, make rm unique_ptr
-		ai.release();
-		cb.release();
+		ai = nullptr;
+		cb = nullptr;
 	}
 };
 
@@ -1472,6 +1472,8 @@ void AIGateway::requestActionASAP(std::function<void()> whatToDo)
 		boost::shared_lock<boost::shared_mutex> gsLock(CGameState::mutex);
 		whatToDo();
 	});
+
+	newThread.detach();
 }
 
 void AIGateway::lostHero(HeroPtr h)
@@ -1605,7 +1607,7 @@ void AIStatus::waitTillFree()
 {
 	boost::unique_lock<boost::mutex> lock(mx);
 	while(battle != NO_BATTLE || !remainingQueries.empty() || !objectsBeingVisited.empty() || ongoingHeroMovement)
-		cv.timed_wait(lock, boost::posix_time::milliseconds(10));
+		cv.wait_for(lock, boost::chrono::milliseconds(10));
 }
 
 bool AIStatus::haveTurn()

+ 0 - 4
AI/Nullkiller/AIUtility.cpp

@@ -25,10 +25,6 @@
 namespace NKAI
 {
 
-extern boost::thread_specific_ptr<AIGateway> ai;
-
-//extern static const int3 dirs[8];
-
 const CGObjectInstance * ObjectIdRef::operator->() const
 {
 	return cb->getObj(id, false);

+ 4 - 2
AI/Nullkiller/AIUtility.h

@@ -57,6 +57,7 @@ using dwellingContent = std::pair<ui32, std::vector<CreatureID>>;
 namespace NKAI
 {
 struct creInfo;
+class AIGateway;
 class Nullkiller;
 
 const int GOLD_MINE_PRODUCTION = 1000, WOOD_ORE_MINE_PRODUCTION = 2, RESOURCE_MINE_PRODUCTION = 1;
@@ -67,7 +68,8 @@ const int ALLOWED_ROAMING_HEROES = 8;
 extern const float SAFE_ATTACK_CONSTANT;
 extern const int GOLD_RESERVE;
 
-extern boost::thread_specific_ptr<CCallback> cb;
+extern thread_local CCallback * cb;
+extern thread_local AIGateway * ai;
 
 enum HeroRole
 {
@@ -201,7 +203,7 @@ void foreach_tile_pos(CCallback * cbp, const Func & foo) // avoid costly retriev
 template<class Func>
 void foreach_neighbour(const int3 & pos, const Func & foo)
 {
-	CCallback * cbp = cb.get(); // avoid costly retrieval of thread-specific pointer
+	CCallback * cbp = cb; // avoid costly retrieval of thread-specific pointer
 	for(const int3 & dir : int3::getDirs())
 	{
 		const int3 n = pos + dir;

+ 0 - 3
AI/Nullkiller/Behaviors/BuildingBehavior.cpp

@@ -20,9 +20,6 @@
 namespace NKAI
 {
 
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<AIGateway> ai;
-
 using namespace Goals;
 
 std::string BuildingBehavior::toString() const

+ 0 - 3
AI/Nullkiller/Behaviors/BuyArmyBehavior.cpp

@@ -17,9 +17,6 @@
 namespace NKAI
 {
 
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<AIGateway> ai;
-
 using namespace Goals;
 
 std::string BuyArmyBehavior::toString() const

+ 0 - 3
AI/Nullkiller/Behaviors/CaptureObjectsBehavior.cpp

@@ -19,9 +19,6 @@
 namespace NKAI
 {
 
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<AIGateway> ai;
-
 using namespace Goals;
 
 template <typename T>

+ 0 - 3
AI/Nullkiller/Behaviors/ClusterBehavior.cpp

@@ -19,9 +19,6 @@
 namespace NKAI
 {
 
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<AIGateway> ai;
-
 using namespace Goals;
 
 std::string ClusterBehavior::toString() const

+ 0 - 3
AI/Nullkiller/Behaviors/DefenceBehavior.cpp

@@ -25,9 +25,6 @@
 namespace NKAI
 {
 
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<AIGateway> ai;
-
 const float TREAT_IGNORE_RATIO = 2;
 
 using namespace Goals;

+ 0 - 3
AI/Nullkiller/Behaviors/GatherArmyBehavior.cpp

@@ -23,9 +23,6 @@
 namespace NKAI
 {
 
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<AIGateway> ai;
-
 using namespace Goals;
 
 std::string GatherArmyBehavior::toString() const

+ 0 - 3
AI/Nullkiller/Behaviors/RecruitHeroBehavior.cpp

@@ -17,9 +17,6 @@
 namespace NKAI
 {
 
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<AIGateway> ai;
-
 using namespace Goals;
 
 std::string RecruitHeroBehavior::toString() const

+ 0 - 3
AI/Nullkiller/Behaviors/StartupBehavior.cpp

@@ -21,9 +21,6 @@
 namespace NKAI
 {
 
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<AIGateway> ai;
-
 using namespace Goals;
 
 std::string StartupBehavior::toString() const

+ 0 - 3
AI/Nullkiller/Engine/DeepDecomposer.cpp

@@ -24,9 +24,6 @@
 namespace NKAI
 {
 
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<AIGateway> ai;
-
 using namespace Goals;
 
 void DeepDecomposer::reset()

+ 0 - 2
AI/Nullkiller/Engine/FuzzyEngines.cpp

@@ -20,8 +20,6 @@ namespace NKAI
 #define MIN_AI_STRENGTH (0.5f) //lower when combat AI gets smarter
 #define UNGUARDED_OBJECT (100.0f) //we consider unguarded objects 100 times weaker than us
 
-extern boost::thread_specific_ptr<AIGateway> ai;
-
 engineBase::engineBase()
 {
 	rules = new fl::RuleBlock();

+ 1 - 4
AI/Nullkiller/Engine/Nullkiller.cpp

@@ -24,9 +24,6 @@
 namespace NKAI
 {
 
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<AIGateway> ai;
-
 using namespace Goals;
 
 #if NKAI_TRACE_LEVEL >= 1
@@ -341,7 +338,7 @@ void Nullkiller::executeTask(Goals::TTask task)
 
 	try
 	{
-		task->accept(ai.get());
+		task->accept(ai);
 		logAi->trace("Task %s completed in %lld", taskDescr, timeElapsed(start));
 	}
 	catch(goalFulfilledException &)

+ 0 - 3
AI/Nullkiller/Goals/AbstractGoal.cpp

@@ -15,9 +15,6 @@
 namespace NKAI
 {
 
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<AIGateway> ai;
-
 using namespace Goals;
 
 TSubgoal Goals::sptr(const AbstractGoal & tmp)

+ 0 - 3
AI/Nullkiller/Goals/AdventureSpellCast.cpp

@@ -14,9 +14,6 @@
 namespace NKAI
 {
 
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<AIGateway> ai;
-
 using namespace Goals;
 
 bool AdventureSpellCast::operator==(const AdventureSpellCast & other) const

+ 0 - 3
AI/Nullkiller/Goals/BuildBoat.cpp

@@ -15,9 +15,6 @@
 namespace NKAI
 {
 
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<AIGateway> ai;
-
 using namespace Goals;
 
 bool BuildBoat::operator==(const BuildBoat & other) const

+ 0 - 4
AI/Nullkiller/Goals/BuildThis.cpp

@@ -17,12 +17,8 @@
 namespace NKAI
 {
 
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<AIGateway> ai;
-
 using namespace Goals;
 
-
 BuildThis::BuildThis(BuildingID Bid, const CGTownInstance * tid)
 	: ElementarGoal(Goals::BUILD_STRUCTURE)
 {

+ 0 - 3
AI/Nullkiller/Goals/BuyArmy.cpp

@@ -17,9 +17,6 @@
 namespace NKAI
 {
 
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<AIGateway> ai;
-
 using namespace Goals;
 
 bool BuyArmy::operator==(const BuyArmy & other) const

+ 0 - 2
AI/Nullkiller/Goals/CaptureObject.cpp

@@ -18,8 +18,6 @@
 namespace NKAI
 {
 
-extern boost::thread_specific_ptr<CCallback> cb;
-
 using namespace Goals;
 
 bool CaptureObject::operator==(const CaptureObject & other) const

+ 0 - 3
AI/Nullkiller/Goals/CompleteQuest.cpp

@@ -17,9 +17,6 @@
 namespace NKAI
 {
 
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<AIGateway> ai;
-
 using namespace Goals;
 
 bool isKeyMaster(const QuestInfo & q)

+ 0 - 3
AI/Nullkiller/Goals/Composition.cpp

@@ -17,9 +17,6 @@
 namespace NKAI
 {
 
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<AIGateway> ai;
-
 using namespace Goals;
 
 bool Composition::operator==(const Composition & other) const

+ 0 - 3
AI/Nullkiller/Goals/DigAtTile.cpp

@@ -16,9 +16,6 @@
 namespace NKAI
 {
 
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<AIGateway> ai;
-
 using namespace Goals;
 
 bool DigAtTile::operator==(const DigAtTile & other) const

+ 0 - 3
AI/Nullkiller/Goals/DismissHero.cpp

@@ -14,9 +14,6 @@
 namespace NKAI
 {
 
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<AIGateway> ai;
-
 using namespace Goals;
 
 bool DismissHero::operator==(const DismissHero & other) const

+ 0 - 3
AI/Nullkiller/Goals/ExchangeSwapTownHeroes.cpp

@@ -16,9 +16,6 @@
 namespace NKAI
 {
 
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<AIGateway> ai;
-
 using namespace Goals;
 
 ExchangeSwapTownHeroes::ExchangeSwapTownHeroes(

+ 0 - 3
AI/Nullkiller/Goals/ExecuteHeroChain.cpp

@@ -15,9 +15,6 @@
 namespace NKAI
 {
 
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<AIGateway> ai;
-
 using namespace Goals;
 
 ExecuteHeroChain::ExecuteHeroChain(const AIPath & path, const CGObjectInstance * obj)

+ 0 - 3
AI/Nullkiller/Goals/RecruitHero.cpp

@@ -17,9 +17,6 @@
 namespace NKAI
 {
 
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<AIGateway> ai;
-
 using namespace Goals;
 
 std::string RecruitHero::toString() const

+ 0 - 3
AI/Nullkiller/Goals/SaveResources.cpp

@@ -15,9 +15,6 @@
 namespace NKAI
 {
 
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<AIGateway> ai;
-
 using namespace Goals;
 
 bool SaveResources::operator==(const SaveResources & other) const

+ 0 - 3
AI/Nullkiller/Markers/ArmyUpgrade.cpp

@@ -16,9 +16,6 @@
 namespace NKAI
 {
 
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<AIGateway> ai;
-
 using namespace Goals;
 
 ArmyUpgrade::ArmyUpgrade(const AIPath & upgradePath, const CGObjectInstance * upgrader, const ArmyUpgradeInfo & upgrade)

+ 0 - 3
AI/Nullkiller/Markers/HeroExchange.cpp

@@ -17,9 +17,6 @@
 namespace NKAI
 {
 
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<AIGateway> ai;
-
 using namespace Goals;
 
 bool HeroExchange::operator==(const HeroExchange & other) const

+ 0 - 3
AI/Nullkiller/Markers/UnlockCluster.cpp

@@ -16,9 +16,6 @@
 namespace NKAI
 {
 
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<AIGateway> ai;
-
 using namespace Goals;
 
 bool UnlockCluster::operator==(const UnlockCluster & other) const

+ 0 - 3
AI/Nullkiller/Pathfinding/Actions/BattleAction.cpp

@@ -16,9 +16,6 @@
 namespace NKAI
 {
 
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<AIGateway> ai;
-
 namespace AIPathfinding
 {
 	void BattleAction::execute(const CGHeroInstance * hero) const

+ 2 - 5
AI/Nullkiller/Pathfinding/Actions/BoatActions.cpp

@@ -20,14 +20,11 @@
 namespace NKAI
 {
 
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<AIGateway> ai;
-
 namespace AIPathfinding
 {
 	void BuildBoatAction::execute(const CGHeroInstance * hero) const
 	{
-		return Goals::BuildBoat(shipyard).accept(ai.get());
+		return Goals::BuildBoat(shipyard).accept(ai);
 	}
 
 	Goals::TSubgoal BuildBoatAction::decompose(const CGHeroInstance * hero) const
@@ -80,7 +77,7 @@ namespace AIPathfinding
 
 	void SummonBoatAction::execute(const CGHeroInstance * hero) const
 	{
-		Goals::AdventureSpellCast(hero, SpellID::SUMMON_BOAT).accept(ai.get());
+		Goals::AdventureSpellCast(hero, SpellID::SUMMON_BOAT).accept(ai);
 	}
 
 	const ChainActor * SummonBoatAction::getActor(const ChainActor * sourceActor) const

+ 0 - 3
AI/Nullkiller/Pathfinding/Actions/BuyArmyAction.cpp

@@ -16,9 +16,6 @@
 namespace NKAI
 {
 
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<AIGateway> ai;
-
 namespace AIPathfinding
 {
 	void BuyArmyAction::execute(const CGHeroInstance * hero) const

+ 0 - 3
AI/Nullkiller/Pathfinding/Actions/QuestAction.cpp

@@ -16,9 +16,6 @@
 namespace NKAI
 {
 
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<AIGateway> ai;
-
 namespace AIPathfinding
 {
 	bool QuestAction::canAct(const AIPathNode * node) const

+ 1 - 4
AI/Nullkiller/Pathfinding/Actions/TownPortalAction.cpp

@@ -18,9 +18,6 @@ namespace NKAI
 
 using namespace AIPathfinding;
 
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<AIGateway> ai;
-
 void TownPortalAction::execute(const CGHeroInstance * hero) const
 {
 	auto goal = Goals::AdventureSpellCast(hero, SpellID::TOWN_PORTAL);
@@ -28,7 +25,7 @@ void TownPortalAction::execute(const CGHeroInstance * hero) const
 	goal.town = target;
 	goal.tile = target->visitablePos();
 
-	goal.accept(ai.get());
+	goal.accept(ai);
 }
 
 std::string TownPortalAction::toString() const

+ 1 - 1
AI/StupidAI/StupidAI.cpp

@@ -108,7 +108,7 @@ void CStupidAI::yourTacticPhase(int distance)
 
 void CStupidAI::activeStack( const CStack * stack )
 {
-	//boost::this_thread::sleep(boost::posix_time::seconds(2));
+	//boost::this_thread::sleep_for(boost::chrono::seconds(2));
 	print("activeStack called for " + stack->nodeName());
 	ReachabilityInfo dists = cb->getReachability(stack);
 	std::vector<EnemyInfo> enemiesShootable, enemiesReachable, enemiesUnreachable;

+ 0 - 4
AI/VCAI/AIUtility.cpp

@@ -21,12 +21,8 @@
 #include "../../lib/mapObjects/CQuest.h"
 #include "../../lib/mapping/CMapDefines.h"
 
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<VCAI> ai;
 extern FuzzyHelper * fh;
 
-//extern static const int3 dirs[8];
-
 const CGObjectInstance * ObjectIdRef::operator->() const
 {
 	return cb->getObj(id, false);

+ 4 - 2
AI/VCAI/AIUtility.h

@@ -18,6 +18,7 @@
 #include "../../lib/mapObjects/CGHeroInstance.h"
 #include "../../CCallback.h"
 
+class VCAI;
 class CCallback;
 struct creInfo;
 
@@ -33,7 +34,8 @@ const int ALLOWED_ROAMING_HEROES = 8;
 extern const double SAFE_ATTACK_CONSTANT;
 extern const int GOLD_RESERVE;
 
-extern boost::thread_specific_ptr<CCallback> cb;
+extern thread_local CCallback * cb;
+extern thread_local VCAI * ai;
 
 //provisional class for AI to store a reference to an owned hero object
 //checks if it's valid on access, should be used in place of const CGHeroInstance*
@@ -192,7 +194,7 @@ void foreach_tile_pos(CCallback * cbp, const Func & foo) // avoid costly retriev
 template<class Func>
 void foreach_neighbour(const int3 & pos, const Func & foo)
 {
-	CCallback * cbp = cb.get(); // avoid costly retrieval of thread-specific pointer
+	CCallback * cbp = cb; // avoid costly retrieval of thread-specific pointer
 	for(const int3 & dir : int3::getDirs())
 	{
 		const int3 n = pos + dir;

+ 0 - 3
AI/VCAI/FuzzyEngines.cpp

@@ -18,9 +18,6 @@
 #define MIN_AI_STRENGTH (0.5f) //lower when combat AI gets smarter
 #define UNGUARDED_OBJECT (100.0f) //we consider unguarded objects 100 times weaker than us
 
-extern boost::thread_specific_ptr<VCAI> ai;
-extern FuzzyHelper * fh;
-
 engineBase::engineBase()
 {
 	rules = new fl::RuleBlock();

+ 1 - 4
AI/VCAI/FuzzyHelper.cpp

@@ -23,9 +23,6 @@
 
 FuzzyHelper * fh;
 
-extern boost::thread_specific_ptr<VCAI> ai;
-extern boost::thread_specific_ptr<CCallback> cb;
-
 Goals::TSubgoal FuzzyHelper::chooseSolution(Goals::TGoalVec vec)
 {
 	if(vec.empty())
@@ -216,7 +213,7 @@ void FuzzyHelper::setPriority(Goals::TSubgoal & g) //calls evaluate - Visitor pa
 
 ui64 FuzzyHelper::evaluateDanger(crint3 tile, const CGHeroInstance * visitor)
 {
-	return evaluateDanger(tile, visitor, ai.get());
+	return evaluateDanger(tile, visitor, ai);
 }
 
 ui64 FuzzyHelper::evaluateDanger(crint3 tile, const CGHeroInstance * visitor, const VCAI * ai)

+ 2 - 0
AI/VCAI/FuzzyHelper.h

@@ -51,3 +51,5 @@ public:
 	ui64 evaluateDanger(crint3 tile, const CGHeroInstance * visitor, const VCAI * ai);
 	ui64 evaluateDanger(crint3 tile, const CGHeroInstance * visitor);
 };
+
+extern FuzzyHelper * fh;

+ 0 - 4
AI/VCAI/Goals/AbstractGoal.cpp

@@ -16,10 +16,6 @@
 #include "../BuildingManager.h"
 #include "../../../lib/StringConstants.h"
 
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<VCAI> ai;
-extern FuzzyHelper * fh;
-
 using namespace Goals;
 
 TSubgoal Goals::sptr(const AbstractGoal & tmp)

+ 0 - 4
AI/VCAI/Goals/AdventureSpellCast.cpp

@@ -14,10 +14,6 @@
 #include "../AIhelper.h"
 #include "../../../lib/mapObjects/CGTownInstance.h"
 
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<VCAI> ai;
-extern FuzzyHelper * fh;
-
 using namespace Goals;
 
 bool AdventureSpellCast::operator==(const AdventureSpellCast & other) const

+ 0 - 5
AI/VCAI/Goals/Build.cpp

@@ -19,11 +19,6 @@
 #include "../../../lib/mapObjects/CGTownInstance.h"
 #include "../../../lib/StringConstants.h"
 
-
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<VCAI> ai;
-extern FuzzyHelper * fh;
-
 using namespace Goals;
 
 TGoalVec Build::getAllPossibleSubgoals()

+ 0 - 4
AI/VCAI/Goals/BuildBoat.cpp

@@ -13,10 +13,6 @@
 #include "../FuzzyHelper.h"
 #include "../AIhelper.h"
 
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<VCAI> ai;
-extern FuzzyHelper * fh;
-
 using namespace Goals;
 
 bool BuildBoat::operator==(const BuildBoat & other) const

+ 0 - 5
AI/VCAI/Goals/BuildThis.cpp

@@ -18,11 +18,6 @@
 #include "../../../lib/mapObjects/CGTownInstance.h"
 #include "../../../lib/StringConstants.h"
 
-
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<VCAI> ai;
-extern FuzzyHelper * fh;
-
 using namespace Goals;
 
 bool BuildThis::operator==(const BuildThis & other) const

+ 0 - 5
AI/VCAI/Goals/BuyArmy.cpp

@@ -13,11 +13,6 @@
 #include "../AIhelper.h"
 #include "../../../lib/mapObjects/CGTownInstance.h"
 
-
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<VCAI> ai;
-extern FuzzyHelper * fh;
-
 using namespace Goals;
 
 bool BuyArmy::operator==(const BuyArmy & other) const

+ 0 - 5
AI/VCAI/Goals/ClearWayTo.cpp

@@ -16,11 +16,6 @@
 #include "../FuzzyHelper.h"
 #include "../AIhelper.h"
 
-
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<VCAI> ai;
-extern FuzzyHelper * fh;
-
 using namespace Goals;
 
 bool ClearWayTo::operator==(const ClearWayTo & other) const

+ 0 - 5
AI/VCAI/Goals/CollectRes.cpp

@@ -18,11 +18,6 @@
 #include "../../../lib/mapObjects/CGMarket.h"
 #include "../../../lib/StringConstants.h"
 
-
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<VCAI> ai;
-extern FuzzyHelper * fh;
-
 using namespace Goals;
 
 bool CollectRes::operator==(const CollectRes & other) const

+ 0 - 4
AI/VCAI/Goals/CompleteQuest.cpp

@@ -14,10 +14,6 @@
 #include "../AIhelper.h"
 #include "../../../lib/mapObjects/CQuest.h"
 
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<VCAI> ai;
-extern FuzzyHelper * fh;
-
 using namespace Goals;
 
 bool CompleteQuest::operator==(const CompleteQuest & other) const

+ 0 - 5
AI/VCAI/Goals/Conquer.cpp

@@ -17,11 +17,6 @@
 #include "../BuildingManager.h"
 #include "../../../lib/StringConstants.h"
 
-
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<VCAI> ai;
-extern FuzzyHelper * fh;
-
 using namespace Goals;
 
 bool Conquer::operator==(const Conquer & other) const

+ 0 - 5
AI/VCAI/Goals/DigAtTile.cpp

@@ -13,11 +13,6 @@
 #include "../VCAI.h"
 #include "../AIUtility.h"
 
-
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<VCAI> ai;
-extern FuzzyHelper * fh;
-
 using namespace Goals;
 
 bool DigAtTile::operator==(const DigAtTile & other) const

+ 2 - 6
AI/VCAI/Goals/Explore.cpp

@@ -18,10 +18,6 @@
 #include "../../../lib/StringConstants.h"
 #include "../../../lib/CPlayerState.h"
 
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<VCAI> ai;
-extern FuzzyHelper * fh;
-
 using namespace Goals;
 
 namespace Goals
@@ -41,8 +37,8 @@ namespace Goals
 
 		ExplorationHelper(HeroPtr h, bool gatherArmy)
 		{
-			cbp = cb.get();
-			aip = ai.get();
+			cbp = cb;
+			aip = ai;
 			hero = h;
 			ts = cbp->getPlayerTeam(ai->playerID);
 			sightRadius = hero->getSightRadius();

+ 0 - 4
AI/VCAI/Goals/FindObj.cpp

@@ -14,10 +14,6 @@
 #include "../VCAI.h"
 #include "../AIUtility.h"
 
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<VCAI> ai;
-extern FuzzyHelper * fh;
-
 using namespace Goals;
 
 bool FindObj::operator==(const FindObj & other) const

+ 0 - 5
AI/VCAI/Goals/GatherArmy.cpp

@@ -18,11 +18,6 @@
 #include "../../../lib/mapObjects/CGTownInstance.h"
 #include "../../../lib/StringConstants.h"
 
-
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<VCAI> ai;
-extern FuzzyHelper * fh;
-
 using namespace Goals;
 
 bool GatherArmy::operator==(const GatherArmy & other) const

+ 0 - 5
AI/VCAI/Goals/GatherTroops.cpp

@@ -18,11 +18,6 @@
 #include "../../../lib/mapObjects/CGTownInstance.h"
 #include "../../../lib/StringConstants.h"
 
-
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<VCAI> ai;
-extern FuzzyHelper * fh;
-
 using namespace Goals;
 
 bool GatherTroops::operator==(const GatherTroops & other) const

+ 1 - 6
AI/VCAI/Goals/GetArtOfType.cpp

@@ -13,11 +13,6 @@
 #include "../VCAI.h"
 #include "../AIUtility.h"
 
-
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<VCAI> ai;
-extern FuzzyHelper * fh;
-
 using namespace Goals;
 
 bool GetArtOfType::operator==(const GetArtOfType & other) const
@@ -28,4 +23,4 @@ bool GetArtOfType::operator==(const GetArtOfType & other) const
 TSubgoal GetArtOfType::whatToDoToAchieve()
 {
 	return sptr(FindObj(Obj::ARTIFACT, aid));
-}
+}

+ 0 - 5
AI/VCAI/Goals/RecruitHero.cpp

@@ -17,11 +17,6 @@
 #include "../BuildingManager.h"
 #include "../../../lib/StringConstants.h"
 
-
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<VCAI> ai;
-extern FuzzyHelper * fh;
-
 using namespace Goals;
 
 TSubgoal RecruitHero::whatToDoToAchieve()

+ 0 - 4
AI/VCAI/Goals/VisitHero.cpp

@@ -18,10 +18,6 @@
 #include "../ResourceManager.h"
 #include "../BuildingManager.h"
 
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<VCAI> ai;
-extern FuzzyHelper * fh;
-
 using namespace Goals;
 
 bool VisitHero::operator==(const VisitHero & other) const

+ 0 - 5
AI/VCAI/Goals/VisitObj.cpp

@@ -17,11 +17,6 @@
 #include "../BuildingManager.h"
 #include "../../../lib/StringConstants.h"
 
-
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<VCAI> ai;
-extern FuzzyHelper * fh;
-
 using namespace Goals;
 
 bool VisitObj::operator==(const VisitObj & other) const

+ 0 - 5
AI/VCAI/Goals/VisitTile.cpp

@@ -17,11 +17,6 @@
 #include "../BuildingManager.h"
 #include "../../../lib/StringConstants.h"
 
-
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<VCAI> ai;
-extern FuzzyHelper * fh;
-
 using namespace Goals;
 
 bool VisitTile::operator==(const VisitTile & other) const

+ 0 - 5
AI/VCAI/Goals/Win.cpp

@@ -19,11 +19,6 @@
 #include "../../../lib/mapObjects/CGTownInstance.h"
 #include "../../../lib/StringConstants.h"
 
-
-extern boost::thread_specific_ptr<CCallback> cb;
-extern boost::thread_specific_ptr<VCAI> ai;
-extern FuzzyHelper * fh;
-
 using namespace Goals;
 
 TSubgoal Win::whatToDoToAchieve()

+ 11 - 9
AI/VCAI/VCAI.cpp

@@ -38,8 +38,8 @@ extern FuzzyHelper * fh;
 const double SAFE_ATTACK_CONSTANT = 1.5;
 
 //one thread may be turn of AI and another will be handling a side effect for AI2
-boost::thread_specific_ptr<CCallback> cb;
-boost::thread_specific_ptr<VCAI> ai;
+thread_local CCallback * cb = nullptr;
+thread_local VCAI * ai = nullptr;
 
 //std::map<int, std::map<int, int> > HeroView::infosCount;
 
@@ -48,18 +48,18 @@ struct SetGlobalState
 {
 	SetGlobalState(VCAI * AI)
 	{
-		assert(!ai.get());
-		assert(!cb.get());
+		assert(!ai);
+		assert(!cb);
 
-		ai.reset(AI);
-		cb.reset(AI->myCb.get());
+		ai = AI;
+		cb = AI->myCb.get();
 	}
 	~SetGlobalState()
 	{
 		//TODO: how to handle rm? shouldn't be called after ai is destroyed, hopefully
 		//TODO: to ensure that, make rm unique_ptr
-		ai.release();
-		cb.release();
+		ai = nullptr;
+		cb = nullptr;
 	}
 };
 
@@ -2497,6 +2497,8 @@ void VCAI::requestActionASAP(std::function<void()> whatToDo)
 		boost::shared_lock<boost::shared_mutex> gsLock(CGameState::mutex);
 		whatToDo();
 	});
+
+	newThread.detach();
 }
 
 void VCAI::lostHero(HeroPtr h)
@@ -2675,7 +2677,7 @@ void AIStatus::waitTillFree()
 {
 	boost::unique_lock<boost::mutex> lock(mx);
 	while(battle != NO_BATTLE || !remainingQueries.empty() || !objectsBeingVisited.empty() || ongoingHeroMovement)
-		cv.timed_wait(lock, boost::posix_time::milliseconds(100));
+		cv.wait_for(lock, boost::chrono::milliseconds(100));
 }
 
 bool AIStatus::haveTurn()

+ 6 - 3
Global.h

@@ -149,8 +149,8 @@ static_assert(sizeof(bool) == 1, "Bool needs to be 1 byte in size.");
 #include <boost/algorithm/string.hpp>
 #include <boost/crc.hpp>
 #include <boost/current_function.hpp>
-#include <boost/date_time/posix_time/posix_time.hpp>
-#include <boost/date_time/posix_time/posix_time_io.hpp>
+#include <boost/date_time/posix_time/posix_time_types.hpp>
+#include <boost/date_time/posix_time/time_formatters.hpp>
 #include <boost/filesystem.hpp>
 #include <boost/filesystem/fstream.hpp>
 #include <boost/filesystem/path.hpp>
@@ -165,7 +165,10 @@ static_assert(sizeof(bool) == 1, "Bool needs to be 1 byte in size.");
 #include <boost/range/adaptor/filtered.hpp>
 #include <boost/range/adaptor/reversed.hpp>
 #include <boost/range/algorithm.hpp>
-#include <boost/thread.hpp>
+#include <boost/thread/thread_only.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/recursive_mutex.hpp>
+#include <boost/thread/once.hpp>
 
 #ifndef M_PI
 #  define M_PI 3.14159265358979323846

+ 11 - 8
client/CMT.cpp

@@ -27,11 +27,12 @@
 #include "render/IScreenHandler.h"
 #include "render/Graphics.h"
 
-#include "../lib/filesystem/Filesystem.h"
+#include "../lib/CConfigHandler.h"
 #include "../lib/CGeneralTextHandler.h"
+#include "../lib/CThreadHelper.h"
 #include "../lib/VCMIDirs.h"
 #include "../lib/VCMI_Lib.h"
-#include "../lib/CConfigHandler.h"
+#include "../lib/filesystem/Filesystem.h"
 
 #include "../lib/logging/CBasicLogConfigurator.h"
 
@@ -53,8 +54,6 @@
 namespace po = boost::program_options;
 namespace po_style = boost::program_options::command_line_style;
 
-extern boost::thread_specific_ptr<bool> inGuiThread;
-
 static po::variables_map vm;
 
 #ifndef VCMI_IOS
@@ -297,7 +296,11 @@ int main(int argc, char * argv[])
 
 #ifndef VCMI_NO_THREADED_LOAD
 	//we can properly play intro only in the main thread, so we have to move loading to the separate thread
-	boost::thread loading(init);
+	boost::thread loading([]()
+	{
+		setThreadName("initialize");
+		init();
+	});
 #else
 	init();
 #endif
@@ -411,7 +414,7 @@ int main(int argc, char * argv[])
 	else
 	{
 		while(true)
-			boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
+			boost::this_thread::sleep_for(boost::chrono::milliseconds(1000));
 	}
 
 	return 0;
@@ -429,7 +432,7 @@ void playIntro()
 
 static void mainLoop()
 {
-	inGuiThread.reset(new bool(true));
+	setThreadName("MainGUI");
 
 	while(1) //main SDL events loop
 	{
@@ -470,7 +473,7 @@ static void quitApplication()
 
 	vstd::clear_pointer(console);// should be removed after everything else since used by logging
 
-	boost::this_thread::sleep(boost::posix_time::milliseconds(750));//???
+	boost::this_thread::sleep_for(boost::chrono::milliseconds(750));//???
 
 	if(!settings["session"]["headless"].Bool())
 		GH.screenHandler().close();

+ 4 - 4
client/CMusicHandler.cpp

@@ -238,7 +238,7 @@ void CSoundHandler::setChannelVolume(int channel, ui32 percent)
 
 void CSoundHandler::setCallback(int channel, std::function<void()> function)
 {
-	boost::unique_lock lockGuard(mutexCallbacks);
+	boost::mutex::scoped_lock lockGuard(mutexCallbacks);
 
 	auto iter = callbacks.find(channel);
 
@@ -251,7 +251,7 @@ void CSoundHandler::setCallback(int channel, std::function<void()> function)
 
 void CSoundHandler::soundFinishedCallback(int channel)
 {
-	boost::unique_lock lockGuard(mutexCallbacks);
+	boost::mutex::scoped_lock lockGuard(mutexCallbacks);
 
 	if (callbacks.count(channel) == 0)
 		return;
@@ -272,14 +272,14 @@ void CSoundHandler::soundFinishedCallback(int channel)
 
 void CSoundHandler::initCallback(int channel)
 {
-	boost::unique_lock lockGuard(mutexCallbacks);
+	boost::mutex::scoped_lock lockGuard(mutexCallbacks);
 	assert(callbacks.count(channel) == 0);
 	callbacks[channel] = {};
 }
 
 void CSoundHandler::initCallback(int channel, const std::function<void()> & function)
 {
-	boost::unique_lock lockGuard(mutexCallbacks);
+	boost::mutex::scoped_lock lockGuard(mutexCallbacks);
 	assert(callbacks.count(channel) == 0);
 	callbacks[channel].push_back(function);
 }

+ 5 - 4
client/CPlayerInterface.cpp

@@ -76,6 +76,7 @@
 #include "../lib/UnlockGuard.h"
 #include "../lib/RoadHandler.h"
 #include "../lib/TerrainHandler.h"
+#include "../lib/CThreadHelper.h"
 #include "CServerHandler.h"
 // FIXME: only needed for CGameState::mutex
 #include "../lib/gameState/CGameState.h"
@@ -135,7 +136,6 @@ CPlayerInterface::CPlayerInterface(PlayerColor Player):
 	makingTurn = false;
 	showingDialog = new CondSh<bool>(false);
 	cingconsole = new CInGameConsole();
-	GH.terminate_cond->set(false);
 	firstCall = 1; //if loading will be overwritten in serialize
 	autosaveCount = 0;
 	isAutoFightOn = false;
@@ -1447,7 +1447,7 @@ void CPlayerInterface::centerView (int3 pos, int focusTime)
 		{
 			auto unlockPim = vstd::makeUnlockGuard(*pim);
 			IgnoreEvents ignore(*this);
-			boost::this_thread::sleep(boost::posix_time::milliseconds(focusTime));
+			boost::this_thread::sleep_for(boost::chrono::milliseconds(focusTime));
 		}
 	}
 	CCS->curh->show();
@@ -1591,7 +1591,6 @@ void CPlayerInterface::gameOver(PlayerColor player, const EVictoryLossCheckResul
 		{
 			if(adventureInt)
 			{
-				GH.terminate_cond->setn(true);
 				GH.windows().popWindows(GH.windows().count());
 				adventureInt.reset();
 			}
@@ -1874,7 +1873,7 @@ void CPlayerInterface::waitForAllDialogs(bool unlockPim)
 	while(!dialogs.empty())
 	{
 		auto unlock = vstd::makeUnlockGuardIf(*pim, unlockPim);
-		boost::this_thread::sleep(boost::posix_time::milliseconds(5));
+		boost::this_thread::sleep_for(boost::chrono::milliseconds(5));
 	}
 	waitWhileDialog(unlockPim);
 }
@@ -1933,6 +1932,8 @@ void CPlayerInterface::setMovementStatus(bool value)
 
 void CPlayerInterface::doMoveHero(const CGHeroInstance * h, CGPath path)
 {
+	setThreadName("doMoveHero");
+
 	int i = 1;
 	auto getObj = [&](int3 coord, bool ignoreHero)
 	{

+ 13 - 12
client/CServerHandler.cpp

@@ -231,7 +231,7 @@ void CServerHandler::startLocalServerAndConnect()
 	while(!androidTestServerReadyFlag.load())
 	{
 		logNetwork->info("still waiting...");
-		boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
+		boost::this_thread::sleep_for(boost::chrono::milliseconds(1000));
 	}
 	logNetwork->info("waiting for server finished...");
 	androidTestServerReadyFlag = false;
@@ -261,7 +261,7 @@ void CServerHandler::justConnectToServer(const std::string & addr, const ui16 po
 		catch(std::runtime_error & error)
 		{
 			logNetwork->warn("\nCannot establish connection. %s Retrying in 1 second", error.what());
-			boost::this_thread::sleep(boost::posix_time::seconds(1));
+			boost::this_thread::sleep_for(boost::chrono::milliseconds(1000));
 		}
 	}
 
@@ -307,7 +307,7 @@ void CServerHandler::stopServerConnection()
 {
 	if(c->handler)
 	{
-		while(!c->handler->timed_join(boost::posix_time::milliseconds(50)))
+		while(!c->handler->timed_join(boost::chrono::milliseconds(50)))
 			applyPacksOnLobbyScreen();
 		c->handler->join();
 	}
@@ -574,6 +574,8 @@ void CServerHandler::startMapAfterConnection(std::shared_ptr<CMapInfo> to)
 
 void CServerHandler::startGameplay(VCMI_LIB_WRAP_NAMESPACE(CGameState) * gameState)
 {
+	setThreadName("startGameplay");
+
 	if(CMM)
 		CMM->disable();
 	client = new CClient();
@@ -630,7 +632,6 @@ void CServerHandler::endGameplay(bool closeConnection, bool restart)
 	{
 		if(CMM)
 		{
-			GH.terminate_cond->setn(false);
 			GH.curInt = CMM.get();
 			CMM->enable();
 		}
@@ -761,20 +762,20 @@ void CServerHandler::debugStartTest(std::string filename, bool save)
 	else
 		startLocalServerAndConnect();
 
-	boost::this_thread::sleep(boost::posix_time::milliseconds(100));
+	boost::this_thread::sleep_for(boost::chrono::milliseconds(100));
 
 	while(!settings["session"]["headless"].Bool() && !GH.windows().topWindow<CLobbyScreen>())
-		boost::this_thread::sleep(boost::posix_time::milliseconds(50));
+		boost::this_thread::sleep_for(boost::chrono::milliseconds(50));
 
 	while(!mi || mapInfo->fileURI != CSH->mi->fileURI)
 	{
 		setMapInfo(mapInfo);
-		boost::this_thread::sleep(boost::posix_time::milliseconds(50));
+		boost::this_thread::sleep_for(boost::chrono::milliseconds(50));
 	}
 	// "Click" on color to remove us from it
 	setPlayer(myFirstColor());
 	while(myFirstColor() != PlayerColor::CANNOT_DETERMINE)
-		boost::this_thread::sleep(boost::posix_time::milliseconds(50));
+		boost::this_thread::sleep_for(boost::chrono::milliseconds(50));
 
 	while(true)
 	{
@@ -787,7 +788,7 @@ void CServerHandler::debugStartTest(std::string filename, bool save)
 		{
 
 		}
-		boost::this_thread::sleep(boost::posix_time::milliseconds(50));
+		boost::this_thread::sleep_for(boost::chrono::milliseconds(50));
 	}
 }
 
@@ -817,7 +818,7 @@ public:
 
 void CServerHandler::threadHandleConnection()
 {
-	setThreadName("CServerHandler::threadHandleConnection");
+	setThreadName("handleConnection");
 	c->enterLobbyConnectionMode();
 
 	try
@@ -826,7 +827,7 @@ void CServerHandler::threadHandleConnection()
 		while(c->connected)
 		{
 			while(state == EClientState::STARTING)
-				boost::this_thread::sleep(boost::posix_time::milliseconds(10));
+				boost::this_thread::sleep_for(boost::chrono::milliseconds(10));
 
 			CPack * pack = c->retrievePack();
 			if(state == EClientState::DISCONNECTING)
@@ -898,7 +899,7 @@ void CServerHandler::visitForClient(CPackForClient & clientPack)
 void CServerHandler::threadRunServer()
 {
 #if !defined(VCMI_MOBILE)
-	setThreadName("CServerHandler::threadRunServer");
+	setThreadName("runServer");
 	const std::string logName = (VCMIDirs::get().userLogsPath() / "server_log.txt").string();
 	std::string comm = VCMIDirs::get().serverPath().string()
 		+ " --port=" + std::to_string(getHostPort())

+ 1 - 1
client/CVideoHandler.cpp

@@ -461,7 +461,7 @@ bool CVideoPlayer::playVideo(int x, int y, bool stopOnKey)
 		double frameDurationSec = packet_duration * av_q2d(format->streams[stream]->time_base);
 		uint32_t timeToSleepMillisec = 1000 * (frameDurationSec);
 
-		boost::this_thread::sleep(boost::posix_time::millisec(timeToSleepMillisec));
+		boost::this_thread::sleep_for(boost::chrono::milliseconds(timeToSleepMillisec));
 	}
 
 	return true;

+ 2 - 0
client/adventureMap/CInGameConsole.cpp

@@ -27,6 +27,7 @@
 
 #include "../../CCallback.h"
 #include "../../lib/CConfigHandler.h"
+#include "../../lib/CThreadHelper.h"
 #include "../../lib/TextOperations.h"
 #include "../../lib/mapObjects/CArmedInstance.h"
 
@@ -255,6 +256,7 @@ void CInGameConsole::endEnteringText(bool processEnteredText)
 			//some commands like gosolo don't work when executed from GUI thread
 			auto threadFunction = [=]()
 			{
+				setThreadName("processCommand");
 				ClientCommandManager commandController;
 				commandController.processCommand(txt.substr(1), true);
 			};

+ 3 - 3
client/battle/BattleInterface.cpp

@@ -43,6 +43,7 @@
 #include "../../lib/NetPacks.h"
 #include "../../lib/UnlockGuard.h"
 #include "../../lib/TerrainHandler.h"
+#include "../../lib/CThreadHelper.h"
 
 BattleInterface::BattleInterface(const CCreatureSet *army1, const CCreatureSet *army2,
 		const CGHeroInstance *hero1, const CGHeroInstance *hero2,
@@ -104,11 +105,9 @@ void BattleInterface::playIntroSoundAndUnlockInterface()
 {
 	auto onIntroPlayed = [this]()
 	{
+		boost::unique_lock<boost::recursive_mutex> un(*CPlayerInterface::pim);
 		if(LOCPLINT->battleInt)
-		{
-			boost::unique_lock<boost::recursive_mutex> un(*CPlayerInterface::pim);
 			onIntroSoundPlayed();
-		}
 	};
 
 	int battleIntroSoundChannel = CCS->soundh->playSoundFromSet(CCS->soundh->battleIntroSounds);
@@ -731,6 +730,7 @@ void BattleInterface::requestAutofightingAIToTakeAction()
 			// HOWEVER this thread won't atttempt to lock game state, potentially leading to races
 			boost::thread aiThread([this, activeStack]()
 			{
+				setThreadName("autofightingAI");
 				curInt->autofightingAI->activeStack(activeStack);
 			});
 			aiThread.detach();

+ 1 - 1
client/battle/BattleWindow.cpp

@@ -407,7 +407,7 @@ void BattleWindow::bFleef()
 		auto txt = boost::format(CGI->generaltexth->allTexts[340]) % heroName; //The Shackles of War are present.  %s can not retreat!
 
 		//printing message
-		owner.curInt->showInfoDialog(boost::to_string(txt), comps);
+		owner.curInt->showInfoDialog(boost::str(txt), comps);
 	}
 }
 

+ 0 - 8
client/eventsSDL/InputSourceKeyboard.cpp

@@ -59,14 +59,6 @@ void InputSourceKeyboard::handleEventKeyDown(const SDL_KeyboardEvent & key)
 		Settings s = settings.write["session"];
 		switch(key.keysym.sym)
 		{
-			case SDLK_F5:
-				if(settings["session"]["spectate-locked-pim"].Bool())
-					CPlayerInterface::pim->unlock();
-				else
-					CPlayerInterface::pim->lock();
-				s["spectate-locked-pim"].Bool() = !settings["session"]["spectate-locked-pim"].Bool();
-				break;
-
 			case SDLK_F6:
 				s["spectate-ignore-hero"].Bool() = !settings["session"]["spectate-ignore-hero"].Bool();
 				break;

+ 6 - 20
client/gui/CGuiHandler.cpp

@@ -36,7 +36,7 @@
 
 CGuiHandler GH;
 
-boost::thread_specific_ptr<bool> inGuiThread;
+static thread_local bool inGuiThread = false;
 
 SObjectConstruction::SObjectConstruction(CIntObject *obj)
 :myObj(obj)
@@ -69,6 +69,8 @@ SSetCaptureState::~SSetCaptureState()
 
 void CGuiHandler::init()
 {
+	inGuiThread = true;
+
 	inputHandlerInstance = std::make_unique<InputHandler>();
 	eventDispatcherInstance = std::make_unique<EventDispatcher>();
 	windowHandlerInstance = std::make_unique<WindowHandler>();
@@ -109,20 +111,8 @@ void CGuiHandler::stopTextInput()
 
 void CGuiHandler::renderFrame()
 {
-	// Updating GUI requires locking pim mutex (that protects screen and GUI state).
-	// During game:
-	// When ending the game, the pim mutex might be hold by other thread,
-	// that will notify us about the ending game by setting terminate_cond flag.
-	//in PreGame terminate_cond stay false
-
-	bool acquiredTheLockOnPim = false; //for tracking whether pim mutex locking succeeded
-	while(!terminate_cond->get() && !(acquiredTheLockOnPim = CPlayerInterface::pim->try_lock())) //try acquiring long until it succeeds or we are told to terminate
-		boost::this_thread::sleep(boost::posix_time::milliseconds(1));
-
-	if(acquiredTheLockOnPim)
 	{
-		// If we are here, pim mutex has been successfully locked - let's store it in a safe RAII lock.
-		boost::unique_lock<boost::recursive_mutex> un(*CPlayerInterface::pim, boost::adopt_lock);
+		boost::recursive_mutex::scoped_lock un(*CPlayerInterface::pim);
 
 		if(nullptr != curInt)
 			curInt->update();
@@ -150,14 +140,10 @@ CGuiHandler::CGuiHandler()
 	, captureChildren(false)
 	, curInt(nullptr)
 	, fakeStatusBar(std::make_shared<EmptyStatusBar>())
-	, terminate_cond (new CondSh<bool>(false))
 {
 }
 
-CGuiHandler::~CGuiHandler()
-{
-	delete terminate_cond;
-}
+CGuiHandler::~CGuiHandler() = default;
 
 ShortcutHandler & CGuiHandler::shortcuts()
 {
@@ -207,7 +193,7 @@ void CGuiHandler::drawFPSCounter()
 
 bool CGuiHandler::amIGuiThread()
 {
-	return inGuiThread.get() && *inGuiThread;
+	return inGuiThread;
 }
 
 void CGuiHandler::dispatchMainThread(const std::function<void()> & functor)

+ 0 - 2
client/gui/CGuiHandler.h

@@ -99,8 +99,6 @@ public:
 
 	/// Calls provided functor in main thread on next execution frame
 	void dispatchMainThread(const std::function<void()> & functor);
-
-	CondSh<bool> * terminate_cond; // confirm termination
 };
 
 extern CGuiHandler GH; //global gui handler

+ 4 - 3
client/mainmenu/CMainMenu.cpp

@@ -392,7 +392,6 @@ std::shared_ptr<CMainMenu> CMainMenu::create()
 	if(!CMM)
 		CMM = std::shared_ptr<CMainMenu>(new CMainMenu());
 
-	GH.terminate_cond->setn(false);
 	return CMM;
 }
 
@@ -562,12 +561,14 @@ void CSimpleJoinScreen::startConnectThread(const std::string & addr, ui16 port)
 	// https://github.com/libsdl-org/SDL/blob/main/docs/README-android.md#threads-and-the-java-vm
 	CVCMIServer::reuseClientJNIEnv(SDL_AndroidGetJNIEnv());
 #endif
-	boost::thread(&CSimpleJoinScreen::connectThread, this, addr, port);
+	boost::thread connector(&CSimpleJoinScreen::connectThread, this, addr, port);
+
+	connector.detach();
 }
 
 void CSimpleJoinScreen::connectThread(const std::string & addr, ui16 port)
 {
-	setThreadName("CSimpleJoinScreen::connectThread");
+	setThreadName("connectThread");
 	if(!addr.length())
 		CSH->startLocalServerAndConnect();
 	else

+ 1 - 1
client/mapView/mapHandler.cpp

@@ -38,7 +38,7 @@ void CMapHandler::waitForOngoingAnimations()
 	while(CGI->mh->hasOngoingAnimations())
 	{
 		auto unlockPim = vstd::makeUnlockGuard(*CPlayerInterface::pim);
-		boost::this_thread::sleep(boost::posix_time::milliseconds(1));
+		boost::this_thread::sleep_for(boost::chrono::milliseconds(1));
 	}
 }
 

+ 1 - 1
client/windows/CSpellWindow.cpp

@@ -562,7 +562,7 @@ void CSpellWindow::SpellArea::hover(bool on)
 	if(mySpell)
 	{
 		if(on)
-			owner->statusBar->write(boost::to_string(boost::format("%s (%s)") % mySpell->getNameTranslated() % CGI->generaltexth->allTexts[171+mySpell->level]));
+			owner->statusBar->write(boost::str(boost::format("%s (%s)") % mySpell->getNameTranslated() % CGI->generaltexth->allTexts[171+mySpell->level]));
 		else
 			owner->statusBar->clear();
 	}

+ 2 - 2
lib/CConsoleHandler.cpp

@@ -214,7 +214,7 @@ void CConsoleHandler::setColor(EConsoleTextColor::EConsoleTextColor color)
 
 int CConsoleHandler::run() const
 {
-	setThreadName("CConsoleHandler::run");
+	setThreadName("consoleHandler");
 	//disabling sync to make in_avail() work (othervice always returns 0)
 	{
 		TLockGuard _(smx);
@@ -233,7 +233,7 @@ int CConsoleHandler::run() const
 					(*cb)(buffer, false);
 		}
 		else
-			boost::this_thread::sleep(boost::posix_time::millisec(100));
+			boost::this_thread::sleep_for(boost::chrono::milliseconds(100));
 
 		boost::this_thread::interruption_point();
 #else

+ 2 - 7
lib/CRandomGenerator.cpp

@@ -13,8 +13,6 @@
 
 VCMI_LIB_NAMESPACE_BEGIN
 
-boost::thread_specific_ptr<CRandomGenerator> CRandomGenerator::defaultRand;
-
 CRandomGenerator::CRandomGenerator()
 {
 	resetSeed();
@@ -84,11 +82,8 @@ double CRandomGenerator::nextDouble()
 
 CRandomGenerator & CRandomGenerator::getDefault()
 {
-	if(!defaultRand.get())
-	{
-		defaultRand.reset(new CRandomGenerator());
-	}
-	return *defaultRand;
+	static thread_local CRandomGenerator defaultRand;
+	return defaultRand;
 }
 
 TGenerator & CRandomGenerator::getStdGenerator()

+ 0 - 1
lib/CRandomGenerator.h

@@ -80,7 +80,6 @@ public:
 
 private:
 	TGenerator rand;
-	static boost::thread_specific_ptr<CRandomGenerator> defaultRand;
 
 public:
 	template <typename Handler>

+ 5 - 3
lib/CThreadHelper.cpp

@@ -29,10 +29,12 @@ CThreadHelper::CThreadHelper(std::vector<std::function<void()>> * Tasks, int Thr
 }
 void CThreadHelper::run()
 {
-	boost::thread_group grupa;
+	std::vector<boost::thread> group;
 	for(int i=0;i<threads;i++)
-		grupa.create_thread(std::bind(&CThreadHelper::processTasks,this));
-	grupa.join_all();
+		group.emplace_back(std::bind(&CThreadHelper::processTasks,this));
+
+	for (auto & thread : group)
+		thread.join();
 
 	//thread group deletes threads, do not free manually
 }

+ 4 - 4
lib/CThreadHelper.h

@@ -46,15 +46,15 @@ public:
 
 	void run()
 	{
-		boost::thread_group grupa;
+		std::vector<boost::thread> group;
 		for(size_t i=0; i<threads; i++)
 		{
 			std::shared_ptr<Payload> payload = context.at(i);
-
-			grupa.create_thread(std::bind(&ThreadPool::processTasks, this, payload));
+			group.emplace_back(std::bind(&ThreadPool::processTasks, this, payload));
 		}
 
-		grupa.join_all();
+		for (auto & thread : group)
+			thread.join();
 
 		//thread group deletes threads, do not free manually
 	}

+ 1 - 1
lib/logging/CLogger.cpp

@@ -288,7 +288,7 @@ std::string CLogFormatter::format(const LogRecord & record) const
 	boost::algorithm::replace_first(message, "%m", record.message);
 	boost::algorithm::replace_first(message, "%c", boost::posix_time::to_simple_string(record.timeStamp));
 
-	//return boost::to_string (boost::format("%d %d %d[%d] - %d") % dateStream.str() % level % record.domain.getName() % record.threadId % record.message);
+	//return boost::str (boost::format("%d %d %d[%d] - %d") % dateStream.str() % level % record.domain.getName() % record.threadId % record.message);
 
 	return message;
 }

+ 1 - 1
lib/mapObjects/CGCreature.cpp

@@ -69,7 +69,7 @@ std::string CGCreature::getHoverText(const CGHeroInstance * hero) const
 			ms.appendLocalString(EMetaText::GENERAL_TXT,243);
 			break;
 		default: //decision = cost in gold
-			ms.appendRawString(boost::to_string(boost::format(VLC->generaltexth->allTexts[244]) % decision));
+			ms.appendRawString(boost::str(boost::format(VLC->generaltexth->allTexts[244]) % decision));
 			break;
 		}
 

+ 1 - 1
lib/mapObjects/CGHeroInstance.cpp

@@ -1463,7 +1463,7 @@ bool CGHeroInstance::hasVisions(const CGObjectInstance * target, const int subty
 
 	const int distance = static_cast<int>(target->pos.dist2d(visitablePos()));
 
-	//logGlobal->debug(boost::to_string(boost::format("Visions: dist %d, mult %d, range %d") % distance % visionsMultiplier % visionsRange));
+	//logGlobal->debug(boost::str(boost::format("Visions: dist %d, mult %d, range %d") % distance % visionsMultiplier % visionsRange));
 
 	return (distance < visionsRange) && (target->pos.z == pos.z);
 }

+ 1 - 1
lib/rmg/CMapGenerator.cpp

@@ -421,7 +421,7 @@ int CMapGenerator::getNextMonlithIndex()
 	while (true)
 	{
 		if (monolithIndex >= VLC->objtypeh->knownSubObjects(Obj::MONOLITH_TWO_WAY).size())
-			throw rmgException(boost::to_string(boost::format("There is no Monolith Two Way with index %d available!") % monolithIndex));
+			throw rmgException(boost::str(boost::format("There is no Monolith Two Way with index %d available!") % monolithIndex));
 		else
 		{
 			//Skip modded Monoliths which can't beplaced on every terrain

+ 2 - 2
lib/rmg/CRmgTemplate.cpp

@@ -156,7 +156,7 @@ TRmgTemplateZoneId ZoneOptions::getId() const
 void ZoneOptions::setId(TRmgTemplateZoneId value)
 {
 	if(value <= 0)
-		throw std::runtime_error(boost::to_string(boost::format("Zone %d id should be greater than 0.") % id));
+		throw std::runtime_error(boost::str(boost::format("Zone %d id should be greater than 0.") % id));
 	id = value;
 }
 
@@ -650,7 +650,7 @@ std::string CRmgTemplate::CPlayerCountRange::toString() const
 		}
 		else
 		{
-			ret += boost::to_string(boost::format("%d-%d") % p.first % p.second);
+			ret += boost::str(boost::format("%d-%d") % p.first % p.second);
 		}
 	}
 

+ 2 - 2
lib/rmg/RmgMap.cpp

@@ -219,7 +219,7 @@ const CMapGenOptions& RmgMap::getMapGenOptions() const
 void RmgMap::assertOnMap(const int3& tile) const
 {
 	if (!mapInstance->isInTheMap(tile))
-		throw rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile.toString()));
+		throw rmgException(boost::str(boost::format("Tile %s is outside the map") % tile.toString()));
 }
 
 RmgMap::Zones & RmgMap::getZones()
@@ -354,7 +354,7 @@ bool RmgMap::isAllowedSpell(const SpellID & sid) const
 void RmgMap::dump(bool zoneId) const
 {
 	static int id = 0;
-	std::ofstream out(boost::to_string(boost::format("zone_%d.txt") % id++));
+	std::ofstream out(boost::str(boost::format("zone_%d.txt") % id++));
 	int levels = mapInstance->levels();
 	int width =  mapInstance->width;
 	int height = mapInstance->height;

+ 6 - 6
lib/rmg/RmgObject.cpp

@@ -115,7 +115,7 @@ void Object::Instance::setAnyTemplate()
 {
 	auto templates = VLC->objtypeh->getHandlerFor(dObject.ID, dObject.subID)->getTemplates();
 	if(templates.empty())
-		throw rmgException(boost::to_string(boost::format("Did not find any graphics for object (%d,%d)") % dObject.ID % dObject.subID));
+		throw rmgException(boost::str(boost::format("Did not find any graphics for object (%d,%d)") % dObject.ID % dObject.subID));
 
 	dObject.appearance = templates.front();
 	dAccessibleAreaCache.clear();
@@ -128,7 +128,7 @@ void Object::Instance::setTemplate(TerrainId terrain)
 	if (templates.empty())
 	{
 		auto terrainName = VLC->terrainTypeHandler->getById(terrain)->getNameTranslated();
-		throw rmgException(boost::to_string(boost::format("Did not find graphics for object (%d,%d) at %s") % dObject.ID % dObject.subID % terrainName));
+		throw rmgException(boost::str(boost::format("Did not find graphics for object (%d,%d) at %s") % dObject.ID % dObject.subID % terrainName));
 	}
 	dObject.appearance = templates.front();
 	dAccessibleAreaCache.clear();
@@ -328,7 +328,7 @@ void rmg::Object::setGuardedIfMonster(const Instance& object)
 void Object::Instance::finalize(RmgMap & map)
 {
 	if(!map.isOnMap(getPosition(true)))
-		throw rmgException(boost::to_string(boost::format("Position of object %d at %s is outside the map") % dObject.id % getPosition(true).toString()));
+		throw rmgException(boost::str(boost::format("Position of object %d at %s is outside the map") % dObject.id % getPosition(true).toString()));
 	
 	//If no specific template was defined for this object, select any matching
 	if (!dObject.appearance)
@@ -337,7 +337,7 @@ void Object::Instance::finalize(RmgMap & map)
 		auto templates = VLC->objtypeh->getHandlerFor(dObject.ID, dObject.subID)->getTemplates(terrainType->getId());
 		if (templates.empty())
 		{
-			throw rmgException(boost::to_string(boost::format("Did not find graphics for object (%d,%d) at %s (terrain %d)") % dObject.ID % dObject.subID % getPosition(true).toString() % terrainType));
+			throw rmgException(boost::str(boost::format("Did not find graphics for object (%d,%d) at %s (terrain %d)") % dObject.ID % dObject.subID % getPosition(true).toString() % terrainType));
 		}
 		else
 		{
@@ -346,12 +346,12 @@ void Object::Instance::finalize(RmgMap & map)
 	}
 
 	if (dObject.isVisitable() && !map.isOnMap(dObject.visitablePos()))
-		throw rmgException(boost::to_string(boost::format("Visitable tile %s of object %d at %s is outside the map") % dObject.visitablePos().toString() % dObject.id % dObject.pos.toString()));
+		throw rmgException(boost::str(boost::format("Visitable tile %s of object %d at %s is outside the map") % dObject.visitablePos().toString() % dObject.id % dObject.pos.toString()));
 
 	for(const auto & tile : dObject.getBlockedPos())
 	{
 		if(!map.isOnMap(tile))
-			throw rmgException(boost::to_string(boost::format("Tile %s of object %d at %s is outside the map") % tile.toString() % dObject.id % dObject.pos.toString()));
+			throw rmgException(boost::str(boost::format("Tile %s of object %d at %s is outside the map") % tile.toString() % dObject.id % dObject.pos.toString()));
 	}
 
 	for(const auto & tile : getBlockedArea().getTilesVector())

+ 1 - 1
lib/rmg/modificators/Modificator.cpp

@@ -119,7 +119,7 @@ void Modificator::postfunction(Modificator * modificator)
 
 void Modificator::dump()
 {
-	std::ofstream out(boost::to_string(boost::format("seed_%d_modzone_%d_%s.txt") % generator.getRandomSeed() % zone.getId() % getName()));
+	std::ofstream out(boost::str(boost::format("seed_%d_modzone_%d_%s.txt") % generator.getRandomSeed() % zone.getId() % getName()));
 	int levels = map.levels();
 	int width =  map.width();
 	int height = map.height();

+ 1 - 1
lib/rmg/modificators/RiverPlacer.cpp

@@ -387,7 +387,7 @@ void RiverPlacer::connectRiver(const int3 & tile)
 		if(tmplates.size() > 3)
 		{
 			if(tmplates.size() % 4 != 0)
-				throw rmgException(boost::to_string(boost::format("River templates for (%d,%d) at terrain %s, river %s are incorrect") %
+				throw rmgException(boost::str(boost::format("River templates for (%d,%d) at terrain %s, river %s are incorrect") %
 					RIVER_DELTA_ID % RIVER_DELTA_SUBTYPE % zone.getTerrainType() % river->shortIdentifier));
 			
 			std::string targetTemplateName = river->deltaName + std::to_string(deltaOrientations[pos]) + ".def";

+ 2 - 2
lib/rmg/threadpool/ThreadPool.h

@@ -169,7 +169,7 @@ inline void ThreadPool::cancel()
 
 auto ThreadPool::async(std::function<void()>&& f) const -> boost::future<void>
 {
-    using TaskT = boost::packaged_task<void>;
+	using TaskT = boost::packaged_task<void>;
 
     {
         Lock lock(mx);
@@ -189,4 +189,4 @@ auto ThreadPool::async(std::function<void()>&& f) const -> boost::future<void>
     return fut;
 }
 
-VCMI_LIB_NAMESPACE_END
+VCMI_LIB_NAMESPACE_END

+ 2 - 8
server/CGameHandler.cpp

@@ -66,10 +66,6 @@
 #include <vcmi/events/GenericEvents.h>
 #include <vcmi/events/AdventureEvents.h>
 
-#ifndef _MSC_VER
-#include <boost/thread/xtime.hpp>
-#endif
-
 #define COMPLAIN_RET_IF(cond, txt) do {if (cond){complain(txt); return;}} while(0)
 #define COMPLAIN_RET_FALSE_IF(cond, txt) do {if (cond){complain(txt); return false;}} while(0)
 #define COMPLAIN_RET(txt) {complain(txt); return false;}
@@ -973,7 +969,6 @@ void CGameHandler::run(bool resume)
 {
 	LOG_TRACE_PARAMS(logGlobal, "resume=%d", resume);
 
-	using namespace boost::posix_time;
 	for (auto cc : lobby->connections)
 	{
 		auto players = lobby->getAllClientPlayers(cc->connectionID);
@@ -1068,8 +1063,7 @@ void CGameHandler::run(bool resume)
 					if(gs->curB)
 						turnTimerHandler.onBattleLoop(waitTime);
 
-					static time_duration p = milliseconds(waitTime);
-					states.cv.timed_wait(lock, p);
+					states.cv.wait_for(lock, boost::chrono::milliseconds(waitTime));
 				}
 			}
 		}
@@ -2575,7 +2569,7 @@ bool CGameHandler::upgradeCreature(ObjectInstanceID objid, SlotID pos, CreatureI
 	const CArmedInstance * obj = static_cast<const CArmedInstance *>(getObjInstance(objid));
 	if (!obj->hasStackAtSlot(pos))
 	{
-		COMPLAIN_RET("Cannot upgrade, no stack at slot " + boost::to_string(pos));
+		COMPLAIN_RET("Cannot upgrade, no stack at slot " + std::to_string(pos));
 	}
 	UpgradeInfo ui;
 	fillUpgradeInfo(obj, pos, ui);

+ 9 - 6
server/CVCMIServer.cpp

@@ -179,7 +179,7 @@ void CVCMIServer::run()
 	}
 
 	while(state == EServerState::LOBBY || state == EServerState::GAMEPLAY_STARTING)
-		boost::this_thread::sleep(boost::posix_time::milliseconds(50));
+		boost::this_thread::sleep_for(boost::chrono::milliseconds(50));
 
 	logNetwork->info("Thread handling connections ended");
 
@@ -188,14 +188,16 @@ void CVCMIServer::run()
 		gh->run(si->mode == StartInfo::LOAD_GAME);
 	}
 	while(state == EServerState::GAMEPLAY_ENDED)
-		boost::this_thread::sleep(boost::posix_time::milliseconds(50));
+		boost::this_thread::sleep_for(boost::chrono::milliseconds(50));
 }
 
 void CVCMIServer::establishRemoteConnections()
 {
+	setThreadName("establishConnection");
+
 	//wait for host connection
 	while(connections.empty())
-		boost::this_thread::sleep(boost::posix_time::milliseconds(50));
+		boost::this_thread::sleep_for(boost::chrono::milliseconds(50));
 	
 	uuid = cmdLineOptions["lobby-uuid"].as<std::string>();
     int numOfConnections = cmdLineOptions["connections"].as<ui16>();
@@ -229,6 +231,7 @@ void CVCMIServer::connectToRemote(const std::string & addr, int port)
 
 void CVCMIServer::threadAnnounceLobby()
 {
+	setThreadName("announceLobby");
 	while(state != EServerState::SHUTDOWN)
 	{
 		{
@@ -246,7 +249,7 @@ void CVCMIServer::threadAnnounceLobby()
 			}
 		}
 
-		boost::this_thread::sleep(boost::posix_time::milliseconds(50));
+		boost::this_thread::sleep_for(boost::chrono::milliseconds(50));
 	}
 }
 
@@ -265,7 +268,7 @@ void CVCMIServer::prepareToRestart()
 			campaignBonus = si->campState->getBonusID(campaignMap).value_or(-1);
 		}
 		// FIXME: dirry hack to make sure old CGameHandler::run is finished
-		boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
+		boost::this_thread::sleep_for(boost::chrono::milliseconds(1000));
 	}
 	
 	for(auto c : connections)
@@ -419,7 +422,7 @@ public:
 
 void CVCMIServer::threadHandleClient(std::shared_ptr<CConnection> c)
 {
-	setThreadName("CVCMIServer::handleConnection");
+	setThreadName("handleClient");
 	c->enterLobbyConnectionMode();
 
 	while(c->connected)

+ 0 - 7
server/StdInc.h

@@ -11,11 +11,4 @@
 
 #include "../Global.h"
 
-#include <boost/crc.hpp>
-#include <boost/date_time/posix_time/posix_time_types.hpp> //no i/o just types
-#include <boost/random/linear_congruential.hpp>
-#include <boost/random/mersenne_twister.hpp>
-#include <boost/random/variate_generator.hpp>
-#include <boost/system/system_error.hpp>
-
 VCMI_LIB_USING_NAMESPACE

+ 0 - 2
test/CMakeLists.txt

@@ -92,8 +92,6 @@ set(test_HEADERS
 
 		spells/targetConditions/TargetConditionItemFixture.h
 
-		vcai/ResourceManagerTest.h
-
 		mock/BattleFake.h
 		mock/mock_BonusBearer.h
  		mock/mock_IGameCallback.h

+ 1 - 1
test/JsonComparer.cpp

@@ -116,7 +116,7 @@ void JsonComparer::checkEqualJson(const JsonVector & actual, const JsonVector &
 
 	for(size_t idx = 0; idx < sz; idx ++)
 	{
-		auto guard = pushName(boost::to_string(idx));
+		auto guard = pushName(std::to_string(idx));
 
 		checkEqualJson(actual.at(idx), expected.at(idx));
 	}

+ 3 - 3
test/map/MapComparer.cpp

@@ -56,7 +56,7 @@ void checkEqual(const std::set<Element> & actual, const std::set<Element> & expe
 	for(auto elem : expected)
 	{
 		if(!vstd::contains(actual, elem))
-			FAIL() << "Required element not found "+boost::to_string(elem);
+			FAIL() << "Required element not found "+std::to_string(elem);
 	}
 }
 
@@ -202,8 +202,8 @@ void MapComparer::compareObject(const CGObjectInstance * actual, const CGObjectI
 	EXPECT_EQ(actual->instanceName, expected->instanceName);
 	EXPECT_EQ(typeid(actual).name(), typeid(expected).name());//todo: remove and use just comparison
 
-	std::string actualFullID = boost::to_string(boost::format("%s(%d)|%s(%d) %d") % actual->typeName % actual->ID % actual->subTypeName % actual->subID % actual->tempOwner);
-	std::string expectedFullID = boost::to_string(boost::format("%s(%d)|%s(%d) %d") % expected->typeName % expected->ID % expected->subTypeName % expected->subID % expected->tempOwner);
+	std::string actualFullID = boost::str(boost::format("%s(%d)|%s(%d) %d") % actual->typeName % actual->ID % actual->subTypeName % actual->subID % actual->tempOwner);
+	std::string expectedFullID = boost::str(boost::format("%s(%d)|%s(%d) %d") % expected->typeName % expected->ID % expected->subTypeName % expected->subID % expected->tempOwner);
 
 	EXPECT_EQ(actualFullID, expectedFullID);
 

Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels