From 9b097fd91123484e5633b7ae7751890550a5ee98 Mon Sep 17 00:00:00 2001 From: Mark Vejvoda Date: Thu, 7 Nov 2013 18:39:08 +0000 Subject: [PATCH] decouple masterserver from network host game settings into two seperate threads --- source/glest_game/graphics/renderer.cpp | 2 +- source/glest_game/graphics/renderer.h | 2 +- source/glest_game/main/main.cpp | 2 +- source/glest_game/main/program.cpp | 2 +- source/glest_game/main/program.h | 2 +- .../menu/menu_state_connected_game.cpp | 2 +- .../menu/menu_state_connected_game.h | 2 +- .../menu/menu_state_custom_game.cpp | 271 +++++++++++++++--- .../glest_game/menu/menu_state_custom_game.h | 10 +- .../menu/menu_state_masterserver.cpp | 2 +- .../glest_game/menu/menu_state_masterserver.h | 2 +- source/glest_game/menu/menu_state_mods.cpp | 2 +- source/glest_game/menu/menu_state_mods.h | 2 +- .../glest_game/network/server_interface.cpp | 4 +- source/glest_game/network/server_interface.h | 2 +- source/glest_game/sound/sound_renderer.h | 2 +- .../include/platform/common/simple_threads.h | 20 +- .../include/platform/posix/socket.h | 2 - .../platform/common/simple_threads.cpp | 56 ++-- 19 files changed, 300 insertions(+), 89 deletions(-) diff --git a/source/glest_game/graphics/renderer.cpp b/source/glest_game/graphics/renderer.cpp index 8d4c8664..790b20ab 100644 --- a/source/glest_game/graphics/renderer.cpp +++ b/source/glest_game/graphics/renderer.cpp @@ -351,7 +351,7 @@ Renderer::~Renderer() { } } -void Renderer::simpleTask(BaseThread *callingThread) { +void Renderer::simpleTask(BaseThread *callingThread,void *userdata) { // This code reads pixmaps from a queue and saves them to disk Pixmap2D *savePixMapBuffer=NULL; string path=""; diff --git a/source/glest_game/graphics/renderer.h b/source/glest_game/graphics/renderer.h index 63e071c4..cc969f76 100644 --- a/source/glest_game/graphics/renderer.h +++ b/source/glest_game/graphics/renderer.h @@ -684,7 +684,7 @@ private: void renderTile(const Vec2i &pos); void renderQuad(int x, int y, int w, int h, const Texture2D *texture); - void simpleTask(BaseThread *callingThread); + void simpleTask(BaseThread *callingThread,void *userdata); //static static Texture2D::Filter strToTextureFilter(const string &s); diff --git a/source/glest_game/main/main.cpp b/source/glest_game/main/main.cpp index 000339ab..05268cbe 100644 --- a/source/glest_game/main/main.cpp +++ b/source/glest_game/main/main.cpp @@ -124,7 +124,7 @@ std::auto_ptr errorHandlerPtr; #endif class NavtiveLanguageNameListCacheGenerator : public SimpleTaskCallbackInterface { - virtual void simpleTask(BaseThread *callingThread) { + virtual void simpleTask(BaseThread *callingThread,void *userdata) { Lang &lang = Lang::getInstance(); lang.getDiscoveredLanguageList(true); } diff --git a/source/glest_game/main/program.cpp b/source/glest_game/main/program.cpp index 1ef4f158..a8a69c87 100644 --- a/source/glest_game/main/program.cpp +++ b/source/glest_game/main/program.cpp @@ -364,7 +364,7 @@ void Program::eventMouseMove(int x, int y, const MouseState *ms) { } } -void Program::simpleTask(BaseThread *callingThread) { +void Program::simpleTask(BaseThread *callingThread,void *userdata) { loopWorker(); } diff --git a/source/glest_game/main/program.h b/source/glest_game/main/program.h index 352e6793..a9b27cce 100644 --- a/source/glest_game/main/program.h +++ b/source/glest_game/main/program.h @@ -206,7 +206,7 @@ public: void init(WindowGl *window, bool initSound=true, bool toggleFullScreen=false); void exit(); - virtual void simpleTask(BaseThread *callingThread); + virtual void simpleTask(BaseThread *callingThread,void *userdata); void mouseDownLeft(int x, int y); void eventMouseMove(int x, int y, const MouseState *ms); diff --git a/source/glest_game/menu/menu_state_connected_game.cpp b/source/glest_game/menu/menu_state_connected_game.cpp index 8b4caed2..91f4f2db 100644 --- a/source/glest_game/menu/menu_state_connected_game.cpp +++ b/source/glest_game/menu/menu_state_connected_game.cpp @@ -915,7 +915,7 @@ string MenuStateConnectedGame::refreshMapModInfo(string mapInfo) { return ""; } -void MenuStateConnectedGame::simpleTask(BaseThread *callingThread) { +void MenuStateConnectedGame::simpleTask(BaseThread *callingThread,void *userdata) { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); diff --git a/source/glest_game/menu/menu_state_connected_game.h b/source/glest_game/menu/menu_state_connected_game.h index 51413bc3..deda1be2 100644 --- a/source/glest_game/menu/menu_state_connected_game.h +++ b/source/glest_game/menu/menu_state_connected_game.h @@ -289,7 +289,7 @@ private: void loadScenarioInfo(string file, ScenarioInfo *scenarioInfo); void initFactionPreview(const GameSettings *gameSettings); - virtual void simpleTask(BaseThread *callingThread); + virtual void simpleTask(BaseThread *callingThread,void *userdata); string refreshTilesetModInfo(string tilesetInfo); string refreshTechModInfo(string techInfo); string refreshMapModInfo(string mapInfo); diff --git a/source/glest_game/menu/menu_state_custom_game.cpp b/source/glest_game/menu/menu_state_custom_game.cpp index ffb12480..17da9a2b 100644 --- a/source/glest_game/menu/menu_state_custom_game.cpp +++ b/source/glest_game/menu/menu_state_custom_game.cpp @@ -56,6 +56,10 @@ struct FormatString { // ===================================================== // class MenuStateCustomGame // ===================================================== +enum THREAD_NOTIFIER_TYPE { + tnt_MASTERSERVER = 1, + tnt_CLIENTS = 2 +}; MenuStateCustomGame::MenuStateCustomGame(Program *program, MainMenu *mainMenu, bool openNetworkSlots,ParentMenuState parentMenuState, bool autostart, @@ -111,6 +115,8 @@ MenuStateCustomGame::MenuStateCustomGame(Program *program, MainMenu *mainMenu, lastCheckedCRCMapValue = -1; publishToMasterserverThread = NULL; + publishToClientsThread = NULL; + Lang &lang= Lang::getInstance(); NetworkManager &networkManager= NetworkManager::getInstance(); Config &config = Config::getInstance(); @@ -658,9 +664,15 @@ MenuStateCustomGame::MenuStateCustomGame(Program *program, MainMenu *mainMenu, GraphicComponent::applyAllCustomProperties(containerName); static string mutexOwnerId = string(extractFileFromDirectoryPath(__FILE__).c_str()) + string("_") + intToStr(__LINE__); - publishToMasterserverThread = new SimpleTaskThread(this,0,200); + publishToMasterserverThread = new SimpleTaskThread(this,0,300,false,(void *)tnt_MASTERSERVER); publishToMasterserverThread->setUniqueID(mutexOwnerId); + + static string mutexOwnerId2 = string(extractFileFromDirectoryPath(__FILE__).c_str()) + string("_") + intToStr(__LINE__); + publishToClientsThread = new SimpleTaskThread(this,0,200,false,(void *)tnt_CLIENTS,false); + publishToClientsThread->setUniqueID(mutexOwnerId2); + publishToMasterserverThread->start(); + publishToClientsThread->start(); if(openNetworkSlots==true){ if(fileExists(DEFAULT_NETWORKGAME_FILENAME) == true) @@ -835,69 +847,116 @@ void MenuStateCustomGame::reloadUI() { GraphicComponent::reloadFontsForRegisterGraphicComponents(containerName); } -void MenuStateCustomGame::cleanup() { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - if(publishToMasterserverThread != NULL) { +void MenuStateCustomGame::cleanupThread(SimpleTaskThread **thread) { + //printf("LINE: %d *thread = %p\n",__LINE__,*thread); + + if(thread != NULL && *thread != NULL) { + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\n#1 cleanupThread callingThread [%p]\n",*thread); + if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + SimpleTaskThread *threadPtr = *thread; + int value = threadPtr->getUserdataAsInt(); + THREAD_NOTIFIER_TYPE threadType = (THREAD_NOTIFIER_TYPE)value; + + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\n#1. cleanupThread callingThread [%p] value = %d\n",*thread,value); + needToBroadcastServerSettings = false; needToRepublishToMasterserver = false; lastNetworkPing = time(NULL); - publishToMasterserverThread->setThreadOwnerValid(false); + threadPtr->setThreadOwnerValid(false); if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\n#1.. cleanupThread callingThread [%p] value = %d\n",*thread,value); + if(forceWaitForShutdown == true) { time_t elapsed = time(NULL); - publishToMasterserverThread->signalQuit(); - for(;(publishToMasterserverThread->canShutdown(false) == false || - publishToMasterserverThread->getRunningStatus() == true) && + threadPtr->signalQuit(); + + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\n#1a cleanupThread callingThread [%p]\n",*thread); + + for(;(threadPtr->canShutdown(false) == false || + threadPtr->getRunningStatus() == true) && difftime((long int)time(NULL),elapsed) <= 15;) { //sleep(150); } - if(publishToMasterserverThread->canShutdown(true) == true && - publishToMasterserverThread->getRunningStatus() == false) { - delete publishToMasterserverThread; + + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\n#1b cleanupThread callingThread [%p]\n",*thread); + + if(threadPtr->canShutdown(true) == true && + threadPtr->getRunningStatus() == false) { + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\n#1c cleanupThread callingThread [%p]\n",*thread); + + delete threadPtr; + //printf("LINE: %d *thread = %p\n",__LINE__,*thread); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); } else { + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\n#1d cleanupThread callingThread [%p]\n",*thread); + char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s %d] Error cannot shutdown publishToMasterserverThread\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + snprintf(szBuf,8096,"In [%s::%s %d] Error cannot shutdown thread\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); //SystemFlags::OutputDebug(SystemFlags::debugError,szBuf); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("%s",szBuf); if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"%s",szBuf); - publishToMasterserverThread->setOverrideShutdownTask(shutdownTaskStatic); - publishToMasterserverThread->setDeleteSelfOnExecutionDone(true); - publishToMasterserverThread->setDeleteAfterExecute(true); - - //publishToMasterserverThread->cleanup(); + if(threadType == tnt_MASTERSERVER) { + threadPtr->setOverrideShutdownTask(shutdownTaskStatic); + } + threadPtr->setDeleteSelfOnExecutionDone(true); + threadPtr->setDeleteAfterExecute(true); + //printf("LINE: %d *thread = %p\n",__LINE__,*thread); } - publishToMasterserverThread = NULL; + threadPtr = NULL; + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\n#1e cleanupThread callingThread [%p]\n",*thread); } else { - publishToMasterserverThread->signalQuit(); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\n#1f cleanupThread callingThread [%p]\n",*thread); + threadPtr->signalQuit(); sleep(0); - if(publishToMasterserverThread->canShutdown(true) == true && - publishToMasterserverThread->getRunningStatus() == false) { - delete publishToMasterserverThread; + if(threadPtr->canShutdown(true) == true && + threadPtr->getRunningStatus() == false) { + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\n#1g cleanupThread callingThread [%p]\n",*thread); + delete threadPtr; + //printf("LINE: %d *thread = %p\n",__LINE__,*thread); } else { + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\n#1h cleanupThread callingThread [%p]\n",*thread); char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s %d] Error cannot shutdown publishToMasterserverThread\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + snprintf(szBuf,8096,"In [%s::%s %d] Error cannot shutdown thread\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); //SystemFlags::OutputDebug(SystemFlags::debugError,szBuf); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("%s",szBuf); if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"%s",szBuf); - publishToMasterserverThread->setOverrideShutdownTask(shutdownTaskStatic); - publishToMasterserverThread->setDeleteSelfOnExecutionDone(true); - publishToMasterserverThread->setDeleteAfterExecute(true); - //publishToMasterserverThread->cleanup(); + if(threadType == tnt_MASTERSERVER) { + threadPtr->setOverrideShutdownTask(shutdownTaskStatic); + } + threadPtr->setDeleteSelfOnExecutionDone(true); + threadPtr->setDeleteAfterExecute(true); + //printf("LINE: %d *thread = %p\n",__LINE__,*thread); } } - publishToMasterserverThread = NULL; + *thread = NULL; + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\n#2 cleanupThread callingThread [%p]\n",*thread); } + //printf("LINE: %d *thread = %p\n",__LINE__,*thread); +} + +void MenuStateCustomGame::cleanup() { + if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + + if(publishToMasterserverThread) { + //printf("LINE: %d\n",__LINE__); + cleanupThread(&publishToMasterserverThread); + } + if(publishToClientsThread) { + //printf("LINE: %d\n",__LINE__); + cleanupThread(&publishToClientsThread); + } + + //printf("LINE: %d\n",__LINE__); if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); @@ -993,10 +1052,12 @@ void MenuStateCustomGame::mouseClick(int x, int y, MouseButton mouseButton) { soundRenderer.playFx(coreData.getClickSoundA()); MutexSafeWrapper safeMutex((publishToMasterserverThread != NULL ? publishToMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutexCLI((publishToClientsThread != NULL ? publishToClientsThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); needToBroadcastServerSettings = false; needToRepublishToMasterserver = false; lastNetworkPing = time(NULL); safeMutex.ReleaseLock(); + safeMutexCLI.ReleaseLock(); if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); @@ -1018,6 +1079,7 @@ void MenuStateCustomGame::mouseClick(int x, int y, MouseButton mouseButton) { if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"%s\n", getCurrentMapFile().c_str()); MutexSafeWrapper safeMutex((publishToMasterserverThread != NULL ? publishToMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutexCLI((publishToClientsThread != NULL ? publishToClientsThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); loadMapInfo(Map::getMapPath(getCurrentMapFile(),"",false), &mapInfo, true); labelMapInfo.setText(mapInfo.desc); @@ -1037,6 +1099,7 @@ void MenuStateCustomGame::mouseClick(int x, int y, MouseButton mouseButton) { //else if (listBoxAdvanced.getSelectedItemIndex() == 1 && listBoxFogOfWar.mouseClick(x, y)) { else if (checkBoxAdvanced.getValue() == 1 && listBoxFogOfWar.mouseClick(x, y)) { MutexSafeWrapper safeMutex((publishToMasterserverThread != NULL ? publishToMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutexCLI((publishToClientsThread != NULL ? publishToClientsThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); cleanupMapPreviewTexture(); if(checkBoxPublishServer.getValue() == true) { @@ -1050,6 +1113,7 @@ void MenuStateCustomGame::mouseClick(int x, int y, MouseButton mouseButton) { } else if (checkBoxAdvanced.getValue() == 1 && checkBoxAllowObservers.mouseClick(x, y)) { MutexSafeWrapper safeMutex((publishToMasterserverThread != NULL ? publishToMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutexCLI((publishToClientsThread != NULL ? publishToClientsThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); if(checkBoxPublishServer.getValue() == true) { needToRepublishToMasterserver = true; @@ -1064,6 +1128,7 @@ void MenuStateCustomGame::mouseClick(int x, int y, MouseButton mouseButton) { } else if (checkBoxAllowInGameJoinPlayer.mouseClick(x, y)) { MutexSafeWrapper safeMutex((publishToMasterserverThread != NULL ? publishToMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutexCLI((publishToClientsThread != NULL ? publishToClientsThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); if(checkBoxPublishServer.getValue() == true) { needToRepublishToMasterserver = true; @@ -1080,6 +1145,7 @@ void MenuStateCustomGame::mouseClick(int x, int y, MouseButton mouseButton) { } else if (checkBoxAllowNativeLanguageTechtree.mouseClick(x, y)) { MutexSafeWrapper safeMutex((publishToMasterserverThread != NULL ? publishToMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutexCLI((publishToClientsThread != NULL ? publishToClientsThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); if(checkBoxPublishServer.getValue() == true) { needToRepublishToMasterserver = true; @@ -1093,6 +1159,7 @@ void MenuStateCustomGame::mouseClick(int x, int y, MouseButton mouseButton) { } else if (checkBoxAdvanced.getValue() == 1 && checkBoxEnableSwitchTeamMode.mouseClick(x, y)) { MutexSafeWrapper safeMutex((publishToMasterserverThread != NULL ? publishToMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutexCLI((publishToClientsThread != NULL ? publishToClientsThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); if(checkBoxPublishServer.getValue() == true) { needToRepublishToMasterserver = true; @@ -1106,6 +1173,7 @@ void MenuStateCustomGame::mouseClick(int x, int y, MouseButton mouseButton) { } else if (checkBoxAdvanced.getValue() == 1 && listBoxAISwitchTeamAcceptPercent.getEnabled() && listBoxAISwitchTeamAcceptPercent.mouseClick(x, y)) { MutexSafeWrapper safeMutex((publishToMasterserverThread != NULL ? publishToMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutexCLI((publishToClientsThread != NULL ? publishToClientsThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); if(checkBoxPublishServer.getValue() == true) { needToRepublishToMasterserver = true; @@ -1119,6 +1187,7 @@ void MenuStateCustomGame::mouseClick(int x, int y, MouseButton mouseButton) { } else if (checkBoxAdvanced.getValue() == 1 && listBoxFallbackCpuMultiplier.getEditable() == true && listBoxFallbackCpuMultiplier.mouseClick(x, y)) { MutexSafeWrapper safeMutex((publishToMasterserverThread != NULL ? publishToMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutexCLI((publishToClientsThread != NULL ? publishToClientsThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); if(checkBoxPublishServer.getValue() == true) { needToRepublishToMasterserver = true; @@ -1134,6 +1203,7 @@ void MenuStateCustomGame::mouseClick(int x, int y, MouseButton mouseButton) { } else if(listBoxTileset.mouseClick(x, y,advanceToItemStartingWith)) { MutexSafeWrapper safeMutex((publishToMasterserverThread != NULL ? publishToMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutexCLI((publishToClientsThread != NULL ? publishToClientsThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); if(checkBoxPublishServer.getValue() == true) { needToRepublishToMasterserver = true; @@ -1148,6 +1218,8 @@ void MenuStateCustomGame::mouseClick(int x, int y, MouseButton mouseButton) { } else if(listBoxMapFilter.mouseClick(x, y)){ MutexSafeWrapper safeMutex((publishToMasterserverThread != NULL ? publishToMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutexCLI((publishToClientsThread != NULL ? publishToClientsThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + switchToNextMapGroup(listBoxMapFilter.getSelectedItemIndex()-oldListBoxMapfilterIndex); if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"%s\n", getCurrentMapFile().c_str()); @@ -1171,6 +1243,7 @@ void MenuStateCustomGame::mouseClick(int x, int y, MouseButton mouseButton) { reloadFactions(listBoxTechTree.getItemCount() <= 1,(checkBoxScenario.getValue() == true ? scenarioFiles[listBoxScenario.getSelectedItemIndex()] : "")); MutexSafeWrapper safeMutex((publishToMasterserverThread != NULL ? publishToMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutexCLI((publishToClientsThread != NULL ? publishToClientsThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); if(checkBoxPublishServer.getValue() == true) { needToRepublishToMasterserver = true; @@ -1184,6 +1257,8 @@ void MenuStateCustomGame::mouseClick(int x, int y, MouseButton mouseButton) { } else if(checkBoxPublishServer.mouseClick(x, y) && checkBoxPublishServer.getEditable()) { MutexSafeWrapper safeMutex((publishToMasterserverThread != NULL ? publishToMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutexCLI((publishToClientsThread != NULL ? publishToClientsThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + needToRepublishToMasterserver = true; soundRenderer.playFx(coreData.getClickSoundC()); @@ -1195,6 +1270,7 @@ void MenuStateCustomGame::mouseClick(int x, int y, MouseButton mouseButton) { } else if(checkBoxAdvanced.getValue() == 1 && checkBoxNetworkPauseGameForLaggedClients.mouseClick(x, y)) { MutexSafeWrapper safeMutex((publishToMasterserverThread != NULL ? publishToMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutexCLI((publishToClientsThread != NULL ? publishToClientsThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); if(checkBoxPublishServer.getValue() == true) { needToRepublishToMasterserver = true; @@ -1213,6 +1289,7 @@ void MenuStateCustomGame::mouseClick(int x, int y, MouseButton mouseButton) { else { for(int i = 0; i < mapInfo.players; ++i) { MutexSafeWrapper safeMutex((publishToMasterserverThread != NULL ? publishToMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutexCLI((publishToClientsThread != NULL ? publishToClientsThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); // set multiplier if(listBoxRMultiplier[i].mouseClick(x, y)) { @@ -1509,6 +1586,7 @@ void MenuStateCustomGame::loadGameSettings(std::string fileName) { serverInterface->setGameSettings(&gameSettings,false); MutexSafeWrapper safeMutex((publishToMasterserverThread != NULL ? publishToMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutexCLI((publishToClientsThread != NULL ? publishToClientsThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); if(checkBoxPublishServer.getValue() == true) { needToRepublishToMasterserver = true; @@ -1571,6 +1649,8 @@ void MenuStateCustomGame::PlayNow(bool saveGame) { } MutexSafeWrapper safeMutex((publishToMasterserverThread != NULL ? publishToMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutexCLI((publishToClientsThread != NULL ? publishToClientsThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + if(saveGame == true) { saveGameSettingsToFile(SAVED_GAME_FILENAME); } @@ -1644,6 +1724,7 @@ void MenuStateCustomGame::PlayNow(bool saveGame) { } safeMutex.ReleaseLock(true); + safeMutexCLI.ReleaseLock(true); GameSettings gameSettings; loadGameSettings(&gameSettings, true); @@ -1652,6 +1733,7 @@ void MenuStateCustomGame::PlayNow(bool saveGame) { // Send the game settings to each client if we have at least one networked client safeMutex.Lock(); + safeMutexCLI.Lock(); bool dataSynchCheckOk = checkNetworkPlayerDataSynch(true, true, true); @@ -1685,6 +1767,7 @@ void MenuStateCustomGame::PlayNow(bool saveGame) { } safeMutex.ReleaseLock(); + safeMutexCLI.ReleaseLock(); return; } } @@ -1695,6 +1778,7 @@ void MenuStateCustomGame::PlayNow(bool saveGame) { showMessageBox("You cannot start the game because\none or more clients do not have the same game data!", "Data Mismatch Error", false); safeMutex.ReleaseLock(); + safeMutexCLI.ReleaseLock(); return; } else { @@ -1740,6 +1824,7 @@ void MenuStateCustomGame::PlayNow(bool saveGame) { } safeMutex.ReleaseLock(); + safeMutexCLI.ReleaseLock(); return; } } @@ -1766,6 +1851,7 @@ void MenuStateCustomGame::PlayNow(bool saveGame) { needToRepublishToMasterserver = false; lastNetworkPing = time(NULL); safeMutex.ReleaseLock(); + safeMutexCLI.ReleaseLock(); if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); @@ -1780,6 +1866,7 @@ void MenuStateCustomGame::PlayNow(bool saveGame) { } else { safeMutex.ReleaseLock(); + safeMutexCLI.ReleaseLock(); } } } @@ -2214,6 +2301,7 @@ void MenuStateCustomGame::update() { // END MutexSafeWrapper safeMutex((publishToMasterserverThread != NULL ? publishToMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutexCLI((publishToClientsThread != NULL ? publishToClientsThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); try { if(serverInitError == true) { @@ -2335,6 +2423,7 @@ void MenuStateCustomGame::update() { if(this->headlessServerMode == true && serverInterface->getMasterserverAdminRequestLaunch() == true) { serverInterface->setMasterserverAdminRequestLaunch(false); safeMutex.ReleaseLock(); + safeMutexCLI.ReleaseLock(); PlayNow(false); return; @@ -2704,6 +2793,7 @@ void MenuStateCustomGame::update() { if(autostart == true) { autostart = false; safeMutex.ReleaseLock(); + safeMutexCLI.ReleaseLock(); if(autoStartSettings != NULL) { setupUIFromGameSettings(*autoStartSettings); @@ -2850,6 +2940,7 @@ void MenuStateCustomGame::publishToMasterserver() { //string serverinfo=""; MutexSafeWrapper safeMutex((publishToMasterserverThread != NULL ? publishToMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + publishToServerInfo.clear(); if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); @@ -2912,29 +3003,62 @@ void MenuStateCustomGame::publishToMasterserver() { if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); } -void MenuStateCustomGame::setupTask(BaseThread *callingThread) { - MenuStateCustomGame::setupTaskStatic(callingThread); +void MenuStateCustomGame::setupTask(BaseThread *callingThread,void *userdata) { + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\nsetupTask callingThread [%p] userdata [%p]\n",callingThread,userdata); + if(userdata != NULL) { + int value = *((int*)&userdata); + THREAD_NOTIFIER_TYPE threadType = (THREAD_NOTIFIER_TYPE)value; + //printf("\n\nsetupTask callingThread [%p] userdata [%p]\n",callingThread,userdata); + if(threadType == tnt_MASTERSERVER) { + MenuStateCustomGame::setupTaskStatic(callingThread); + } + } } -void MenuStateCustomGame::shutdownTask(BaseThread *callingThread) { - MenuStateCustomGame::shutdownTaskStatic(callingThread); +void MenuStateCustomGame::shutdownTask(BaseThread *callingThread,void *userdata) { + //printf("\n\nshutdownTask callingThread [%p] userdata [%p]\n",callingThread,userdata); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n\nshutdownTask callingThread [%p] userdata [%p]\n",callingThread,userdata); + if(userdata != NULL) { + int value = *((int*)&userdata); + THREAD_NOTIFIER_TYPE threadType = (THREAD_NOTIFIER_TYPE)value; + //printf("\n\nshutdownTask callingThread [%p] userdata [%p]\n",callingThread,userdata); + if(threadType == tnt_MASTERSERVER) { + MenuStateCustomGame::shutdownTaskStatic(callingThread); + } + } } void MenuStateCustomGame::setupTaskStatic(BaseThread *callingThread) { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + CURL *handle = SystemFlags::initHTTP(); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); callingThread->setGenericData(handle); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); } void MenuStateCustomGame::shutdownTaskStatic(BaseThread *callingThread) { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + + //printf("LINE: %d\n",__LINE__); CURL *handle = callingThread->getGenericData(); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); SystemFlags::cleanupHTTP(&handle); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); } -void MenuStateCustomGame::simpleTask(BaseThread *callingThread) { +void MenuStateCustomGame::simpleTask(BaseThread *callingThread,void *userdata) { + //printf("\n\nSimple Task callingThread [%p] userdata [%p]\n",callingThread,userdata); + int value = *((int*)&userdata); + //printf("\n\nSimple Task callingThread [%p] userdata [%p] value = %d\n",callingThread,userdata,value); + THREAD_NOTIFIER_TYPE threadType = (THREAD_NOTIFIER_TYPE)value; + if(threadType == tnt_MASTERSERVER) { + simpleTaskForMasterServer(callingThread); + } + else if(threadType == tnt_CLIENTS) { + simpleTaskForClients(callingThread); + } +} + +void MenuStateCustomGame::simpleTaskForMasterServer(BaseThread *callingThread) { try { //printf("-=-=-=-=- IN MenuStateCustomGame simpleTask - A\n"); @@ -2950,21 +3074,9 @@ void MenuStateCustomGame::simpleTask(BaseThread *callingThread) { needToRepublishToMasterserver = false; std::map newPublishToServerInfo = publishToServerInfo; publishToServerInfo.clear(); - bool broadCastSettings = needToBroadcastServerSettings; //printf("simpleTask broadCastSettings = %d\n",broadCastSettings); - needToBroadcastServerSettings = false; - bool hasClientConnection = false; - - if(broadCastSettings == true) { - ServerInterface *serverInterface = NetworkManager::getInstance().getServerInterface(false); - if(serverInterface != NULL) { - hasClientConnection = serverInterface->hasClientConnection(); - } - } - bool needPing = (difftime((long int)time(NULL),lastNetworkPing) >= GameConstants::networkPingInterval); - if(callingThread->getQuitStatus() == true) { return; } @@ -3043,6 +3155,65 @@ void MenuStateCustomGame::simpleTask(BaseThread *callingThread) { //printf("-=-=-=-=- IN MenuStateCustomGame simpleTask - D\n"); + safeMutex.ReleaseLock(); + + //printf("-=-=-=-=- IN MenuStateCustomGame simpleTask - F\n"); + } + catch(const std::exception &ex) { + char szBuf[8096]=""; + snprintf(szBuf,8096,"In [%s::%s %d]\nError detected:\n%s\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError,szBuf); + if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"%s",szBuf); + + if(callingThread->getQuitStatus() == false) { + //throw megaglest_runtime_error(szBuf); + showGeneralError=true; + generalErrorToShow = ex.what(); + } + } + + if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); +} + +void MenuStateCustomGame::simpleTaskForClients(BaseThread *callingThread) { + try { + //printf("-=-=-=-=- IN MenuStateCustomGame simpleTask - A\n"); + + MutexSafeWrapper safeMutexThreadOwner(callingThread->getMutexThreadOwnerValid(),string(__FILE__) + "_" + intToStr(__LINE__)); + if(callingThread->getQuitStatus() == true || safeMutexThreadOwner.isValidMutex() == false) { + return; + } + + //printf("-=-=-=-=- IN MenuStateCustomGame simpleTask - B\n"); + + MutexSafeWrapper safeMutex(callingThread->getMutexThreadObjectAccessor(),string(__FILE__) + "_" + intToStr(__LINE__)); + bool broadCastSettings = needToBroadcastServerSettings; + + //printf("simpleTask broadCastSettings = %d\n",broadCastSettings); + + needToBroadcastServerSettings = false; + bool hasClientConnection = false; + + if(broadCastSettings == true) { + ServerInterface *serverInterface = NetworkManager::getInstance().getServerInterface(false); + if(serverInterface != NULL) { + hasClientConnection = serverInterface->hasClientConnection(); + } + } + bool needPing = (difftime((long int)time(NULL),lastNetworkPing) >= GameConstants::networkPingInterval); + + if(callingThread->getQuitStatus() == true) { + return; + } + + //printf("-=-=-=-=- IN MenuStateCustomGame simpleTask - C\n"); + + safeMutexThreadOwner.ReleaseLock(); + + if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + + //printf("-=-=-=-=- IN MenuStateCustomGame simpleTask - D\n"); + if(broadCastSettings == true) { MutexSafeWrapper safeMutexThreadOwner2(callingThread->getMutexThreadOwnerValid(),string(__FILE__) + "_" + intToStr(__LINE__)); if(callingThread->getQuitStatus() == true || safeMutexThreadOwner2.isValidMutex() == false) { @@ -4059,6 +4230,8 @@ void MenuStateCustomGame::keyDown(SDL_KeyboardEvent key) { bool handled = keyDownEditLabel(key, &activeInputLabel); if(handled == true) { MutexSafeWrapper safeMutex((publishToMasterserverThread != NULL ? publishToMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutexCLI((publishToClientsThread != NULL ? publishToClientsThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + if(hasNetworkGameSettings() == true) { needToSetChangedGameSettings = true; lastSetChangedGameSettings = time(NULL); @@ -4116,6 +4289,8 @@ void MenuStateCustomGame::keyPress(SDL_KeyboardEvent c) { bool handled = keyPressEditLabel(c, &activeInputLabel); if(handled == true && &labelGameName != activeInputLabel) { MutexSafeWrapper safeMutex((publishToMasterserverThread != NULL ? publishToMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutexCLI((publishToClientsThread != NULL ? publishToClientsThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + if(hasNetworkGameSettings() == true) { needToSetChangedGameSettings = true; lastSetChangedGameSettings = time(NULL); @@ -4435,6 +4610,8 @@ void MenuStateCustomGame::processScenario() { updateNetworkSlots(); MutexSafeWrapper safeMutex((publishToMasterserverThread != NULL ? publishToMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + MutexSafeWrapper safeMutexCLI((publishToClientsThread != NULL ? publishToClientsThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + if(checkBoxPublishServer.getValue() == true) { needToRepublishToMasterserver = true; } diff --git a/source/glest_game/menu/menu_state_custom_game.h b/source/glest_game/menu/menu_state_custom_game.h index 0b82fac0..588adc2e 100644 --- a/source/glest_game/menu/menu_state_custom_game.h +++ b/source/glest_game/menu/menu_state_custom_game.h @@ -156,6 +156,7 @@ private: bool needToBroadcastServerSettings; std::map publishToServerInfo; SimpleTaskThread *publishToMasterserverThread; + SimpleTaskThread *publishToClientsThread; ParentMenuState parentMenuState; int soundConnectionCount; @@ -237,9 +238,9 @@ public: virtual void keyUp(SDL_KeyboardEvent key); - virtual void simpleTask(BaseThread *callingThread); - virtual void setupTask(BaseThread *callingThread); - virtual void shutdownTask(BaseThread *callingThread); + virtual void simpleTask(BaseThread *callingThread,void *userdata); + virtual void setupTask(BaseThread *callingThread,void *userdata); + virtual void shutdownTask(BaseThread *callingThread,void *userdata); static void setupTaskStatic(BaseThread *callingThread); static void shutdownTaskStatic(BaseThread *callingThread); @@ -300,6 +301,9 @@ private: bool checkNetworkPlayerDataSynch(bool checkMapCRC,bool checkTileSetCRC, bool checkTechTreeCRC); + void cleanupThread(SimpleTaskThread **thread); + void simpleTaskForMasterServer(BaseThread *callingThread); + void simpleTaskForClients(BaseThread *callingThread); }; }}//end namespace diff --git a/source/glest_game/menu/menu_state_masterserver.cpp b/source/glest_game/menu/menu_state_masterserver.cpp index a2d55c6f..8d2a7887 100644 --- a/source/glest_game/menu/menu_state_masterserver.cpp +++ b/source/glest_game/menu/menu_state_masterserver.cpp @@ -898,7 +898,7 @@ void MenuStateMasterserver::update() { } } -void MenuStateMasterserver::simpleTask(BaseThread *callingThread) { +void MenuStateMasterserver::simpleTask(BaseThread *callingThread,void *userdata) { if(callingThread->getQuitStatus() == true) { return; } diff --git a/source/glest_game/menu/menu_state_masterserver.h b/source/glest_game/menu/menu_state_masterserver.h index 3d211f7e..7b2f52ab 100644 --- a/source/glest_game/menu/menu_state_masterserver.h +++ b/source/glest_game/menu/menu_state_masterserver.h @@ -126,7 +126,7 @@ public: virtual void keyPress(SDL_KeyboardEvent c); virtual void keyUp(SDL_KeyboardEvent key); - virtual void simpleTask(BaseThread *callingThread); + virtual void simpleTask(BaseThread *callingThread,void *userdata); virtual bool isInSpecialKeyCaptureEvent() { return chatManager.getEditEnabled(); } static void setDisplayMessageFunction(DisplayMessageFunction pDisplayMessage) { pCB_DisplayMessage = pDisplayMessage; } diff --git a/source/glest_game/menu/menu_state_mods.cpp b/source/glest_game/menu/menu_state_mods.cpp index d674fd1d..cbcb6ad9 100644 --- a/source/glest_game/menu/menu_state_mods.cpp +++ b/source/glest_game/menu/menu_state_mods.cpp @@ -392,7 +392,7 @@ void MenuStateMods::reloadUI() { GraphicComponent::reloadFontsForRegisterGraphicComponents(containerName); } -void MenuStateMods::simpleTask(BaseThread *callingThread) { +void MenuStateMods::simpleTask(BaseThread *callingThread,void *userdata) { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__); static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); diff --git a/source/glest_game/menu/menu_state_mods.h b/source/glest_game/menu/menu_state_mods.h index ccf05206..b161b266 100644 --- a/source/glest_game/menu/menu_state_mods.h +++ b/source/glest_game/menu/menu_state_mods.h @@ -193,7 +193,7 @@ public: virtual void keyPress(SDL_KeyboardEvent c); virtual void keyUp(SDL_KeyboardEvent key); - virtual void simpleTask(BaseThread *callingThread); + virtual void simpleTask(BaseThread *callingThread,void *userdata); virtual void reloadUI(); diff --git a/source/glest_game/network/server_interface.cpp b/source/glest_game/network/server_interface.cpp index bda9a0cf..6493a72c 100644 --- a/source/glest_game/network/server_interface.cpp +++ b/source/glest_game/network/server_interface.cpp @@ -275,7 +275,7 @@ ServerInterface::~ServerInterface() { lastMasterserverHeartbeatTime = 0; if(needToRepublishToMasterserver == true) { - simpleTask(NULL); + simpleTask(NULL,NULL); } for(int i= 0; i < GameConstants::maxPlayers; ++i) { @@ -2873,7 +2873,7 @@ void ServerInterface::setGameStats(Stats *stats) { *gameStats = *stats; } -void ServerInterface::simpleTask(BaseThread *callingThread) { +void ServerInterface::simpleTask(BaseThread *callingThread,void *userdata) { MutexSafeWrapper safeMutex(masterServerThreadAccessor,CODE_AT_LINE); if(difftime((long int)time(NULL),lastMasterserverHeartbeatTime) >= MASTERSERVER_HEARTBEAT_GAME_STATUS_SECONDS) { diff --git a/source/glest_game/network/server_interface.h b/source/glest_game/network/server_interface.h index 84949217..c9f77bc7 100644 --- a/source/glest_game/network/server_interface.h +++ b/source/glest_game/network/server_interface.h @@ -226,7 +226,7 @@ public: return serverSynchAccessor; } - virtual void simpleTask(BaseThread *callingThread); + virtual void simpleTask(BaseThread *callingThread,void *userdata); void addClientToServerIPAddress(uint32 clientIp, uint32 ServerIp); virtual int isValidClientType(uint32 clientIp); virtual int isClientAllowedToGetFile(uint32 clientIp, const char *username, const char *filename); diff --git a/source/glest_game/sound/sound_renderer.h b/source/glest_game/sound/sound_renderer.h index 8e084652..0964a532 100644 --- a/source/glest_game/sound/sound_renderer.h +++ b/source/glest_game/sound/sound_renderer.h @@ -65,7 +65,7 @@ public: static SoundRenderer &getInstance(); bool init(Window *window); void update(); - virtual void simpleTask(BaseThread *callingThread) { update(); } + virtual void simpleTask(BaseThread *callingThread,void *userdata) { update(); } SoundPlayer *getSoundPlayer() const {return soundPlayer;} //music diff --git a/source/shared_lib/include/platform/common/simple_threads.h b/source/shared_lib/include/platform/common/simple_threads.h index 308ea27d..2f0e5a1b 100644 --- a/source/shared_lib/include/platform/common/simple_threads.h +++ b/source/shared_lib/include/platform/common/simple_threads.h @@ -71,10 +71,10 @@ typedef void taskFunctionCallback(BaseThread *callingThread); // class SimpleTaskCallbackInterface { public: - virtual void simpleTask(BaseThread *callingThread) = 0; + virtual void simpleTask(BaseThread *callingThread,void *userdata) = 0; - virtual void setupTask(BaseThread *callingThread) { } - virtual void shutdownTask(BaseThread *callingThread) { } + virtual void setupTask(BaseThread *callingThread,void *userdata) { } + virtual void shutdownTask(BaseThread *callingThread,void *userdata) { } virtual ~SimpleTaskCallbackInterface() {} }; @@ -97,14 +97,26 @@ protected: time_t lastExecuteTimestamp; taskFunctionCallback *overrideShutdownTask; + void *userdata; + bool wantSetupAndShutdown; public: SimpleTaskThread(SimpleTaskCallbackInterface *simpleTaskInterface, unsigned int executionCount=0, unsigned int millisecsBetweenExecutions=0, - bool needTaskSignal = false); + bool needTaskSignal = false, + void *userdata=NULL, + bool wantSetupAndShutdown=true); virtual ~SimpleTaskThread(); + virtual void * getUserdata() { return userdata; } + virtual int getUserdataAsInt() { + int value = 0; + if(userdata) { + value = *((int*)&userdata); + } + return value; + } virtual void execute(); virtual bool canShutdown(bool deleteSelfIfShutdownDelayed=false); diff --git a/source/shared_lib/include/platform/posix/socket.h b/source/shared_lib/include/platform/posix/socket.h index 8a5cb9c4..b80a040e 100644 --- a/source/shared_lib/include/platform/posix/socket.h +++ b/source/shared_lib/include/platform/posix/socket.h @@ -164,8 +164,6 @@ public: static int DEFAULT_SOCKET_SENDBUF_SIZE; static int DEFAULT_SOCKET_RECVBUF_SIZE; - //virtual void simpleTask(BaseThread *callingThread); - static int getBroadCastPort() { return broadcast_portno; } static void setBroadCastPort(int value) { broadcast_portno = value; } static std::vector getLocalIPAddressList(); diff --git a/source/shared_lib/sources/platform/common/simple_threads.cpp b/source/shared_lib/sources/platform/common/simple_threads.cpp index f38f33cc..39c27a1a 100644 --- a/source/shared_lib/sources/platform/common/simple_threads.cpp +++ b/source/shared_lib/sources/platform/common/simple_threads.cpp @@ -345,7 +345,8 @@ vector FileCRCPreCacheThread::getPendingTextureList(int maxTextures SimpleTaskThread::SimpleTaskThread( SimpleTaskCallbackInterface *simpleTaskInterface, unsigned int executionCount, unsigned int millisecsBetweenExecutions, - bool needTaskSignal) : BaseThread(), + bool needTaskSignal, + void *userdata, bool wantSetupAndShutdown) : BaseThread(), simpleTaskInterface(NULL), overrideShutdownTask(NULL) { uniqueID = "SimpleTaskThread"; @@ -355,6 +356,11 @@ SimpleTaskThread::SimpleTaskThread( SimpleTaskCallbackInterface *simpleTaskInter this->millisecsBetweenExecutions = millisecsBetweenExecutions; this->needTaskSignal = needTaskSignal; this->overrideShutdownTask = NULL; + this->userdata = userdata; + this->wantSetupAndShutdown = wantSetupAndShutdown; + //if(this->userdata != NULL) { + // printf("IN SImpleThread this->userdata [%p]\n",this->userdata); + //} setTaskSignalled(false); @@ -363,15 +369,18 @@ SimpleTaskThread::SimpleTaskThread( SimpleTaskCallbackInterface *simpleTaskInter mutexLastExecuteTimestamp.setOwnerId(mutexOwnerId); lastExecuteTimestamp = time(NULL); - string mutexOwnerId1 = CODE_AT_LINE; - MutexSafeWrapper safeMutex1(&mutexSimpleTaskInterfaceValid,mutexOwnerId1); - if(this->simpleTaskInterfaceValid == true) { - safeMutex1.ReleaseLock(); - this->simpleTaskInterface->setupTask(this); + if(this->wantSetupAndShutdown == true) { + string mutexOwnerId1 = CODE_AT_LINE; + MutexSafeWrapper safeMutex1(&mutexSimpleTaskInterfaceValid,mutexOwnerId1); + if(this->simpleTaskInterfaceValid == true) { + safeMutex1.ReleaseLock(); + this->simpleTaskInterface->setupTask(this,userdata); + } } } SimpleTaskThread::~SimpleTaskThread() { + //printf("~SimpleTaskThread LINE: %d this = %p\n",__LINE__,this); try { cleanup(); } @@ -382,22 +391,33 @@ SimpleTaskThread::~SimpleTaskThread() { throw megaglest_runtime_error(ex.what()); //abort(); } + //printf("~SimpleTaskThread LINE: %d this = %p\n",__LINE__,this); } void SimpleTaskThread::cleanup() { - if(this->overrideShutdownTask != NULL) { - this->overrideShutdownTask(this); - this->overrideShutdownTask = NULL; - } - else if(this->simpleTaskInterface != NULL) { - string mutexOwnerId1 = CODE_AT_LINE; - MutexSafeWrapper safeMutex1(&mutexSimpleTaskInterfaceValid,mutexOwnerId1); - if(this->simpleTaskInterfaceValid == true) { - safeMutex1.ReleaseLock(); - this->simpleTaskInterface->shutdownTask(this); - this->simpleTaskInterface = NULL; + //printf("~SimpleTaskThread LINE: %d this = %p\n",__LINE__,this); + if(this->wantSetupAndShutdown == true) { + if(this->overrideShutdownTask != NULL) { + //printf("~SimpleTaskThread LINE: %d this = %p\n",__LINE__,this); + this->overrideShutdownTask(this); + this->overrideShutdownTask = NULL; + } + else if(this->simpleTaskInterface != NULL) { + //printf("~SimpleTaskThread LINE: %d this = %p\n",__LINE__,this); + string mutexOwnerId1 = CODE_AT_LINE; + MutexSafeWrapper safeMutex1(&mutexSimpleTaskInterfaceValid,mutexOwnerId1); + //printf("~SimpleTaskThread LINE: %d this = %p\n",__LINE__,this); + if(this->simpleTaskInterfaceValid == true) { + //printf("~SimpleTaskThread LINE: %d this = %p\n",__LINE__,this); + safeMutex1.ReleaseLock(); + //printf("~SimpleTaskThread LINE: %d this = %p\n",__LINE__,this); + this->simpleTaskInterface->shutdownTask(this,userdata); + this->simpleTaskInterface = NULL; + //printf("~SimpleTaskThread LINE: %d this = %p\n",__LINE__,this); + } } } + //printf("~SimpleTaskThread LINE: %d this = %p\n",__LINE__,this); } void SimpleTaskThread::setOverrideShutdownTask(taskFunctionCallback *ptr) { @@ -479,7 +499,7 @@ void SimpleTaskThread::execute() { if(getQuitStatus() == false) { ExecutingTaskSafeWrapper safeExecutingTaskMutex(this); //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - this->simpleTaskInterface->simpleTask(this); + this->simpleTaskInterface->simpleTask(this,this->userdata); //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); if(getQuitStatus() == true) {