diff --git a/source/glest_game/game/game.cpp b/source/glest_game/game/game.cpp index 418b704f..c2de21b0 100644 --- a/source/glest_game/game/game.cpp +++ b/source/glest_game/game/game.cpp @@ -1676,14 +1676,29 @@ void Game::renderWorker() { // ==================== tick ==================== void Game::removeUnitFromSelection(const Unit *unit) { - Selection *selection= getGuiPtr()->getSelectionPtr(); - for(int i=0; i < selection->getCount(); ++i) { - const Unit *currentUnit = selection->getUnit(i); - if(currentUnit == unit) { - selection->unSelect(i); - break; + try { + Selection *selection= gui.getSelectionPtr(); + for(int i=0; i < selection->getCount(); ++i) { + const Unit *currentUnit = selection->getUnit(i); + if(currentUnit == unit) { + selection->unSelect(i); + break; + } } } + catch(const exception &ex) { + char szBuf[4096]=""; + sprintf(szBuf,"In [%s::%s Line: %d] Error [%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,szBuf); + + if(errorMessageBox.getEnabled() == false) { + ErrorDisplayMessage(ex.what(),true); + } + + //abort(); + } } void Game::tick() { diff --git a/source/glest_game/type_instances/unit.cpp b/source/glest_game/type_instances/unit.cpp index 641a4812..953ca4c0 100644 --- a/source/glest_game/type_instances/unit.cpp +++ b/source/glest_game/type_instances/unit.cpp @@ -552,7 +552,9 @@ Unit::~Unit() { Renderer &renderer= Renderer::getInstance(); renderer.removeUnitFromQuadCache(this); - game->removeUnitFromSelection(this); + if(game != NULL) { + game->removeUnitFromSelection(this); + } //MutexSafeWrapper safeMutex1(&mutexDeletedUnits,string(__FILE__) + "_" + intToStr(__LINE__)); //deletedUnits[this]=true; diff --git a/source/shared_lib/include/platform/common/base_thread.h b/source/shared_lib/include/platform/common/base_thread.h index 41746d59..f54db28b 100644 --- a/source/shared_lib/include/platform/common/base_thread.h +++ b/source/shared_lib/include/platform/common/base_thread.h @@ -15,6 +15,7 @@ #include "leak_dumper.h" #include "thread.h" #include +#include using namespace Shared::Platform; using namespace std; @@ -41,6 +42,10 @@ protected: Mutex mutexExecutingTask; bool executingTask; + void *ptr; + static Mutex mutexMasterThreadList; + static std::map masterThreadList; + bool quit; bool running; string uniqueID; @@ -90,6 +95,8 @@ public: T * getGenericData() { return genericData; } template void setGenericData(T *value) { genericData = value; } + + static bool isThreadDeleted(void *ptr); }; class RunningStatusSafeWrapper { diff --git a/source/shared_lib/sources/platform/common/base_thread.cpp b/source/shared_lib/sources/platform/common/base_thread.cpp index 8134c3e1..fbe02f7a 100644 --- a/source/shared_lib/sources/platform/common/base_thread.cpp +++ b/source/shared_lib/sources/platform/common/base_thread.cpp @@ -20,9 +20,17 @@ using namespace Shared::Util; namespace Shared { namespace PlatformCommon { -BaseThread::BaseThread() : Thread() { +Mutex BaseThread::mutexMasterThreadList; +std::map BaseThread::masterThreadList; + +BaseThread::BaseThread() : Thread(), ptr(NULL) { if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + ptr = this; + MutexSafeWrapper safeMutexMasterList(&mutexMasterThreadList); + masterThreadList[ptr]++; + safeMutexMasterList.ReleaseLock(); + uniqueID = "base_thread"; setQuitStatus(false); @@ -39,6 +47,28 @@ BaseThread::~BaseThread() { if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] uniqueID [%s]\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str()); bool ret = shutdownAndWait(); if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] uniqueID [%s] ret [%d] END\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str(),ret); + + MutexSafeWrapper safeMutexMasterList(&mutexMasterThreadList); + if(masterThreadList.find(this) == masterThreadList.end()) { + char szBuf[4096]=""; + sprintf(szBuf,"invalid thread delete for ptr: %p",this); + throw runtime_error(szBuf); + } + masterThreadList[this]--; + if(masterThreadList[this] <= 0) { + masterThreadList.erase(this); + } + safeMutexMasterList.ReleaseLock(); +} + +bool BaseThread::isThreadDeleted(void *ptr) { + bool result = false; + MutexSafeWrapper safeMutexMasterList(&mutexMasterThreadList); + if(masterThreadList.find(ptr) != masterThreadList.end()) { + result = (masterThreadList[ptr] <= 0); + } + safeMutexMasterList.ReleaseLock(); + return result; } Mutex * BaseThread::getMutexThreadOwnerValid() { @@ -180,7 +210,9 @@ void BaseThread::setDeleteSelfOnExecutionDone(bool value) { void BaseThread::deleteSelfIfRequired() { if(getDeleteSelfOnExecutionDone() == true) { - delete this; + if(isThreadDeleted(this->ptr) == false) { + delete this; + } return; } } diff --git a/source/shared_lib/sources/platform/common/simple_threads.cpp b/source/shared_lib/sources/platform/common/simple_threads.cpp index 5a8e3231..a08437d8 100644 --- a/source/shared_lib/sources/platform/common/simple_threads.cpp +++ b/source/shared_lib/sources/platform/common/simple_threads.cpp @@ -358,6 +358,7 @@ bool SimpleTaskThread::canShutdown(bool deleteSelfIfShutdownDelayed) { } void SimpleTaskThread::execute() { + void *ptr_cpy = this->ptr; bool mustDeleteSelf = false; { { @@ -424,7 +425,9 @@ void SimpleTaskThread::execute() { } if(mustDeleteSelf == true) { - delete this; + if(isThreadDeleted(ptr_cpy) == false) { + delete this; + } } } @@ -486,6 +489,7 @@ bool LogFileThread::checkSaveCurrentLogBufferToDisk() { } void LogFileThread::execute() { + void *ptr_cpy = this->ptr; bool mustDeleteSelf = false; { RunningStatusSafeWrapper runningStatus(this); @@ -531,7 +535,9 @@ void LogFileThread::execute() { } if(mustDeleteSelf == true) { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] LogFile thread is deleting self\n",__FILE__,__FUNCTION__,__LINE__); - delete this; + if(isThreadDeleted(ptr_cpy) == false) { + delete this; + } return; } }