added mutex protection in custom game menu to protect access to member variables to avoid crashes when background thread and user changes both occur

This commit is contained in:
Mark Vejvoda
2010-06-04 21:46:10 +00:00
parent 052b82541f
commit 2970e5114a
4 changed files with 54 additions and 12 deletions

View File

@@ -317,6 +317,7 @@ void MenuStateCustomGame::mouseClick(int x, int y, MouseButton mouseButton){
CoreData &coreData= CoreData::getInstance(); CoreData &coreData= CoreData::getInstance();
SoundRenderer &soundRenderer= SoundRenderer::getInstance(); SoundRenderer &soundRenderer= SoundRenderer::getInstance();
ServerInterface* serverInterface= NetworkManager::getInstance().getServerInterface(); ServerInterface* serverInterface= NetworkManager::getInstance().getServerInterface();
if(mainMessageBox.getEnabled()){ if(mainMessageBox.getEnabled()){
int button= 1; int button= 1;
if(mainMessageBox.mouseClick(x, y, button)) if(mainMessageBox.mouseClick(x, y, button))
@@ -359,6 +360,7 @@ void MenuStateCustomGame::mouseClick(int x, int y, MouseButton mouseButton){
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
// Send the game settings to each client if we have at least one networked client // Send the game settings to each client if we have at least one networked client
MutexSafeWrapper safeMutex(&masterServerThreadAccessor);
if( hasNetworkGameSettings() == true && if( hasNetworkGameSettings() == true &&
needToSetChangedGameSettings == true) needToSetChangedGameSettings == true)
{ {
@@ -418,6 +420,7 @@ void MenuStateCustomGame::mouseClick(int x, int y, MouseButton mouseButton){
ServerInterface* serverInterface= NetworkManager::getInstance().getServerInterface(); ServerInterface* serverInterface= NetworkManager::getInstance().getServerInterface();
serverInterface->setGameSettings(&gameSettings,false); serverInterface->setGameSettings(&gameSettings,false);
MutexSafeWrapper safeMutex(&masterServerThreadAccessor);
needToRepublishToMasterserver = true; needToRepublishToMasterserver = true;
if(hasNetworkGameSettings() == true) if(hasNetworkGameSettings() == true)
@@ -429,6 +432,8 @@ void MenuStateCustomGame::mouseClick(int x, int y, MouseButton mouseButton){
else if(listBoxMap.mouseClick(x, y)){ else if(listBoxMap.mouseClick(x, y)){
SystemFlags::OutputDebug(SystemFlags::debugSystem,"%s\n", mapFiles[listBoxMap.getSelectedItemIndex()].c_str()); SystemFlags::OutputDebug(SystemFlags::debugSystem,"%s\n", mapFiles[listBoxMap.getSelectedItemIndex()].c_str());
MutexSafeWrapper safeMutex(&masterServerThreadAccessor);
loadMapInfo(Map::getMapPath(mapFiles[listBoxMap.getSelectedItemIndex()]), &mapInfo); loadMapInfo(Map::getMapPath(mapFiles[listBoxMap.getSelectedItemIndex()]), &mapInfo);
labelMapInfo.setText(mapInfo.desc); labelMapInfo.setText(mapInfo.desc);
updateControlers(); updateControlers();
@@ -442,6 +447,7 @@ void MenuStateCustomGame::mouseClick(int x, int y, MouseButton mouseButton){
} }
} }
else if (listBoxFogOfWar.mouseClick(x, y)) { else if (listBoxFogOfWar.mouseClick(x, y)) {
MutexSafeWrapper safeMutex(&masterServerThreadAccessor);
needToRepublishToMasterserver = true; needToRepublishToMasterserver = true;
if(hasNetworkGameSettings() == true) if(hasNetworkGameSettings() == true)
@@ -451,6 +457,7 @@ void MenuStateCustomGame::mouseClick(int x, int y, MouseButton mouseButton){
} }
} }
else if (listBoxEnableObserverMode.mouseClick(x, y)) { else if (listBoxEnableObserverMode.mouseClick(x, y)) {
MutexSafeWrapper safeMutex(&masterServerThreadAccessor);
needToRepublishToMasterserver = true; needToRepublishToMasterserver = true;
if(hasNetworkGameSettings() == true) if(hasNetworkGameSettings() == true)
@@ -460,6 +467,7 @@ void MenuStateCustomGame::mouseClick(int x, int y, MouseButton mouseButton){
} }
} }
else if (listBoxEnableServerControlledAI.mouseClick(x, y)&&listBoxEnableServerControlledAI.getEditable()) { else if (listBoxEnableServerControlledAI.mouseClick(x, y)&&listBoxEnableServerControlledAI.getEditable()) {
MutexSafeWrapper safeMutex(&masterServerThreadAccessor);
needToRepublishToMasterserver = true; needToRepublishToMasterserver = true;
if(hasNetworkGameSettings() == true) if(hasNetworkGameSettings() == true)
@@ -469,6 +477,7 @@ void MenuStateCustomGame::mouseClick(int x, int y, MouseButton mouseButton){
} }
} }
else if(listBoxTileset.mouseClick(x, y)){ else if(listBoxTileset.mouseClick(x, y)){
MutexSafeWrapper safeMutex(&masterServerThreadAccessor);
needToRepublishToMasterserver = true; needToRepublishToMasterserver = true;
if(hasNetworkGameSettings() == true) if(hasNetworkGameSettings() == true)
@@ -480,6 +489,7 @@ void MenuStateCustomGame::mouseClick(int x, int y, MouseButton mouseButton){
else if(listBoxTechTree.mouseClick(x, y)){ else if(listBoxTechTree.mouseClick(x, y)){
reloadFactions(); reloadFactions();
MutexSafeWrapper safeMutex(&masterServerThreadAccessor);
needToRepublishToMasterserver = true; needToRepublishToMasterserver = true;
if(hasNetworkGameSettings() == true) if(hasNetworkGameSettings() == true)
@@ -489,13 +499,13 @@ void MenuStateCustomGame::mouseClick(int x, int y, MouseButton mouseButton){
} }
} }
else if(listBoxPublishServer.mouseClick(x, y)&&listBoxPublishServer.getEditable()){ else if(listBoxPublishServer.mouseClick(x, y)&&listBoxPublishServer.getEditable()){
MutexSafeWrapper safeMutex(&masterServerThreadAccessor);
needToRepublishToMasterserver = true; needToRepublishToMasterserver = true;
soundRenderer.playFx(coreData.getClickSoundC()); soundRenderer.playFx(coreData.getClickSoundC());
} }
else else {
{ for(int i=0; i<mapInfo.players; ++i) {
for(int i=0; i<mapInfo.players; ++i) MutexSafeWrapper safeMutex(&masterServerThreadAccessor);
{
//ensure thet only 1 human player is present //ensure thet only 1 human player is present
if(listBoxControls[i].mouseClick(x, y)) if(listBoxControls[i].mouseClick(x, y))
{ {
@@ -949,14 +959,23 @@ void MenuStateCustomGame::simpleTask() {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
if( needToRepublishToMasterserver == true && MutexSafeWrapper safeMutex(&masterServerThreadAccessor);
publishToServerInfo != "") { bool republish = (needToRepublishToMasterserver == true && publishToServerInfo != "");
safeMutex.ReleaseLock(false);
if(republish == true) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
safeMutex.Lock();
needToRepublishToMasterserver = false; needToRepublishToMasterserver = false;
safeMutex.ReleaseLock(false);
string request = Config::getInstance().getString("Masterserver") + "addServerInfo.php?" + publishToServerInfo; string request = Config::getInstance().getString("Masterserver") + "addServerInfo.php?" + publishToServerInfo;
safeMutex.Lock();
publishToServerInfo = ""; publishToServerInfo = "";
safeMutex.ReleaseLock(false);
printf("the request is:\n%s\n",request.c_str()); printf("the request is:\n%s\n",request.c_str());
@@ -966,18 +985,27 @@ void MenuStateCustomGame::simpleTask() {
//if(serverInfo!="OK") //if(serverInfo!="OK")
if(EndsWith(serverInfo, "OK") == false) if(EndsWith(serverInfo, "OK") == false)
{ {
safeMutex.Lock();
showMasterserverError=true; showMasterserverError=true;
masterServererErrorToShow=serverInfo; masterServererErrorToShow=serverInfo;
safeMutex.ReleaseLock(false);
} }
} }
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
if(needToBroadcastServerSettings) safeMutex.Lock();
bool broadCastSettings = needToBroadcastServerSettings;
safeMutex.ReleaseLock(false);
if(broadCastSettings)
{ {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
safeMutex.Lock();
needToBroadcastServerSettings=false; needToBroadcastServerSettings=false;
safeMutex.ReleaseLock(false);
ServerInterface* serverInterface= NetworkManager::getInstance().getServerInterface(); ServerInterface* serverInterface= NetworkManager::getInstance().getServerInterface();
if(serverInterface->hasClientConnection() == true) { if(serverInterface->hasClientConnection() == true) {
//printf("Sending game settings broadcast since we have at least 1 client connected'\n"); //printf("Sending game settings broadcast since we have at least 1 client connected'\n");
@@ -996,6 +1024,8 @@ void MenuStateCustomGame::simpleTask() {
void MenuStateCustomGame::loadGameSettings(GameSettings *gameSettings) { void MenuStateCustomGame::loadGameSettings(GameSettings *gameSettings) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
MutexSafeWrapper safeMutex(&masterServerThreadAccessor);
int factionCount= 0; int factionCount= 0;
ServerInterface* serverInterface= NetworkManager::getInstance().getServerInterface(); ServerInterface* serverInterface= NetworkManager::getInstance().getServerInterface();
@@ -1054,6 +1084,8 @@ void MenuStateCustomGame::loadGameSettings(GameSettings *gameSettings) {
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] gameSettings->getTech() = [%s]\n",__FILE__,__FUNCTION__,gameSettings->getTech().c_str()); //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] gameSettings->getTech() = [%s]\n",__FILE__,__FUNCTION__,gameSettings->getTech().c_str());
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] gameSettings->getMap() = [%s]\n",__FILE__,__FUNCTION__,gameSettings->getMap().c_str()); //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] gameSettings->getMap() = [%s]\n",__FILE__,__FUNCTION__,gameSettings->getMap().c_str());
safeMutex.ReleaseLock(false);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
} }

View File

@@ -69,6 +69,7 @@ private:
bool needToBroadcastServerSettings; bool needToBroadcastServerSettings;
string publishToServerInfo; string publishToServerInfo;
SimpleTaskThread *publishToMasterserverThread; SimpleTaskThread *publishToMasterserverThread;
Mutex masterServerThreadAccessor;
bool parentMenuIsMs; bool parentMenuIsMs;
int soundConnectionCount; int soundConnectionCount;

View File

@@ -694,6 +694,7 @@ bool ServerInterface::launchGame(const GameSettings* gameSettings){
void ServerInterface::broadcastGameSetup(const GameSettings* gameSettings) { void ServerInterface::broadcastGameSetup(const GameSettings* gameSettings) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
MutexSafeWrapper safeMutex(&serverSynchAccessor);
NetworkMessageLaunch networkMessageLaunch(gameSettings,nmtBroadCastSetup); NetworkMessageLaunch networkMessageLaunch(gameSettings,nmtBroadCastSetup);
broadcastMessage(&networkMessageLaunch); broadcastMessage(&networkMessageLaunch);
@@ -860,6 +861,8 @@ void ServerInterface::setGameSettings(GameSettings *serverGameSettings, bool wai
{ {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] START gameSettingsUpdateCount = %d, waitForClientAck = %d\n",__FILE__,__FUNCTION__,gameSettingsUpdateCount,waitForClientAck); SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] START gameSettingsUpdateCount = %d, waitForClientAck = %d\n",__FILE__,__FUNCTION__,gameSettingsUpdateCount,waitForClientAck);
MutexSafeWrapper safeMutex(&serverSynchAccessor);
if(getAllowGameDataSynchCheck() == true) if(getAllowGameDataSynchCheck() == true)
{ {
if(waitForClientAck == true && gameSettingsUpdateCount > 0) if(waitForClientAck == true && gameSettingsUpdateCount > 0)

View File

@@ -69,19 +69,25 @@ public:
MutexSafeWrapper(Mutex *mutex) { MutexSafeWrapper(Mutex *mutex) {
this->mutex = mutex; this->mutex = mutex;
if(this->mutex != NULL) { Lock();
this->mutex->p();
}
} }
~MutexSafeWrapper() { ~MutexSafeWrapper() {
ReleaseLock(); ReleaseLock();
} }
void ReleaseLock() {
void Lock() {
if(this->mutex != NULL) {
this->mutex->p();
}
}
void ReleaseLock(bool keepMutex=false) {
if(this->mutex != NULL) { if(this->mutex != NULL) {
this->mutex->v(); this->mutex->v();
if(keepMutex == false) {
this->mutex = NULL; this->mutex = NULL;
} }
} }
}
}; };
// ===================================================== // =====================================================