浏览代码

Merge pull request #2406 from IvanSavenko/fix_mutex

Fix game hang/crash on locking mutex
Ivan Savenko 2 年之前
父节点
当前提交
eccd8590f5
共有 5 个文件被更改,包括 32 次插入5 次删除
  1. 2 1
      AI/BattleAI/BattleAI.h
  2. 13 1
      AI/StupidAI/StupidAI.cpp
  3. 3 0
      AI/StupidAI/StupidAI.h
  4. 12 3
      client/eventsSDL/InputHandler.cpp
  5. 2 0
      client/eventsSDL/InputHandler.h

+ 2 - 1
AI/BattleAI/BattleAI.h

@@ -59,7 +59,8 @@ class CBattleAI : public CBattleGameInterface
 	std::shared_ptr<Environment> env;
 
 	//Previous setting of cb
-	bool wasWaitingForRealize, wasUnlockingGs;
+	bool wasWaitingForRealize;
+	bool wasUnlockingGs;
 	int movesSkippedByDefense;
 
 public:

+ 13 - 1
AI/StupidAI/StupidAI.cpp

@@ -18,14 +18,21 @@ static std::shared_ptr<CBattleCallback> cbc;
 
 CStupidAI::CStupidAI()
 	: side(-1)
+	, wasWaitingForRealize(false)
+	, wasUnlockingGs(false)
 {
 	print("created");
 }
 
-
 CStupidAI::~CStupidAI()
 {
 	print("destroyed");
+	if(cb)
+	{
+		//Restore previous state of CB - it may be shared with the main AI (like VCAI)
+		cb->waitTillRealize = wasWaitingForRealize;
+		cb->unlockGsWhenWaiting = wasUnlockingGs;
+	}
 }
 
 void CStupidAI::initBattleInterface(std::shared_ptr<Environment> ENV, std::shared_ptr<CBattleCallback> CB)
@@ -33,6 +40,11 @@ void CStupidAI::initBattleInterface(std::shared_ptr<Environment> ENV, std::share
 	print("init called, saving ptr to IBattleCallback");
 	env = ENV;
 	cbc = cb = CB;
+
+	wasWaitingForRealize = CB->waitTillRealize;
+	wasUnlockingGs = CB->unlockGsWhenWaiting;
+	CB->waitTillRealize = false;
+	CB->unlockGsWhenWaiting = false;
 }
 
 void CStupidAI::actionFinished(const BattleAction &action)

+ 3 - 0
AI/StupidAI/StupidAI.h

@@ -20,6 +20,9 @@ class CStupidAI : public CBattleGameInterface
 	std::shared_ptr<CBattleCallback> cb;
 	std::shared_ptr<Environment> env;
 
+	bool wasWaitingForRealize;
+	bool wasUnlockingGs;
+
 	void print(const std::string &text) const;
 public:
 	CStupidAI();

+ 12 - 3
client/eventsSDL/InputHandler.cpp

@@ -70,13 +70,22 @@ void InputHandler::handleCurrentEvent(const SDL_Event & current)
 	}
 }
 
-void InputHandler::processEvents()
+std::vector<SDL_Event> InputHandler::acquireEvents()
 {
 	boost::unique_lock<boost::mutex> lock(eventsMutex);
-	for(const auto & currentEvent : eventsQueue)
+
+	std::vector<SDL_Event> result;
+	std::swap(result, eventsQueue);
+	return result;
+}
+
+void InputHandler::processEvents()
+{
+	std::vector<SDL_Event> eventsToProcess = acquireEvents();
+
+	for(const auto & currentEvent : eventsToProcess)
 		handleCurrentEvent(currentEvent);
 
-	eventsQueue.clear();
 	fingerHandler->handleUpdate();
 }
 

+ 2 - 0
client/eventsSDL/InputHandler.h

@@ -29,6 +29,8 @@ class InputHandler
 
 	Point cursorPosition;
 
+	std::vector<SDL_Event> acquireEvents();
+
 	void preprocessEvent(const SDL_Event & event);
 	void handleCurrentEvent(const SDL_Event & current);
 	void handleUserEvent(const SDL_UserEvent & current);