diff --git a/source/shared_lib/include/platform/common/base_thread.h b/source/shared_lib/include/platform/common/base_thread.h index 54019600..04fb107e 100644 --- a/source/shared_lib/include/platform/common/base_thread.h +++ b/source/shared_lib/include/platform/common/base_thread.h @@ -52,11 +52,15 @@ protected: bool hasBeginExecution; bool deleteSelfOnExecutionDone; + Mutex mutexStarted; + bool started; + virtual void setQuitStatus(bool value); void deleteSelfIfRequired(); void *genericData; + public: BaseThread(); virtual ~BaseThread(); @@ -66,6 +70,9 @@ public: virtual bool getQuitStatus(); virtual bool getRunningStatus(); + virtual bool getStarted(); + virtual void setStarted(bool value); + virtual bool getHasBeginExecution(); virtual void setHasBeginExecution(bool value); diff --git a/source/shared_lib/include/platform/sdl/thread.h b/source/shared_lib/include/platform/sdl/thread.h index c34fa593..89913bf4 100644 --- a/source/shared_lib/include/platform/sdl/thread.h +++ b/source/shared_lib/include/platform/sdl/thread.h @@ -58,6 +58,9 @@ public: private: SDL_Thread* thread; + std::auto_ptr mutexthreadAccessor; + bool threadObjectValid(); + bool deleteAfterExecute; static Mutex mutexthreadList; static vector threadList; diff --git a/source/shared_lib/sources/platform/common/base_thread.cpp b/source/shared_lib/sources/platform/common/base_thread.cpp index add1dd15..eaf32de7 100644 --- a/source/shared_lib/sources/platform/common/base_thread.cpp +++ b/source/shared_lib/sources/platform/common/base_thread.cpp @@ -36,6 +36,7 @@ BaseThread::BaseThread() : Thread(), ptr(NULL), genericData(NULL) { setQuitStatus(false); setRunningStatus(false); + setStarted(false); setHasBeginExecution(false); setExecutingTask(false); setDeleteSelfOnExecutionDone(false); @@ -47,6 +48,16 @@ BaseThread::BaseThread() : Thread(), ptr(NULL), genericData(NULL) { BaseThread::~BaseThread() { //printf("In ~BaseThread Line: %d uniqueID [%s]\n",__LINE__,uniqueID.c_str()); + if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] uniqueID [%s]\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str()); + + //BaseThread *base_thread = dynamic_cast(this); + if(this->getStarted() == false) { + time_t elapsed = time(NULL); + for(;this->getStarted() == false && + difftime((long int)time(NULL),elapsed) <= 3;) { + sleep(5); + } + } 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(); @@ -88,6 +99,28 @@ BaseThread::~BaseThread() { //printf("In ~BaseThread Line: %d uniqueID [%s] [%p]\n",__LINE__,uniqueID.c_str(),this); } +bool BaseThread::getStarted() { + static string mutexOwnerId = CODE_AT_LINE; + MutexSafeWrapper safeMutex(&mutexStarted,mutexOwnerId); + mutexStarted.setOwnerId(mutexOwnerId); + bool retval = started; + safeMutex.ReleaseLock(); + + return retval; +} + +void BaseThread::setStarted(bool value) { + if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] uniqueID [%s]\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str()); + + static string mutexOwnerId = CODE_AT_LINE; + MutexSafeWrapper safeMutex(&mutexStarted,mutexOwnerId); + mutexStarted.setOwnerId(mutexOwnerId); + started = value; + safeMutex.ReleaseLock(); + + 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 BaseThread::isThreadDeleted(void *ptr) { bool result = false; MutexSafeWrapper safeMutexMasterList(&mutexMasterThreadList); @@ -106,7 +139,7 @@ Mutex * BaseThread::getMutexThreadOwnerValid() { } void BaseThread::setThreadOwnerValid(bool value) { - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + static string mutexOwnerId = CODE_AT_LINE; MutexSafeWrapper safeMutex(&mutexThreadOwnerValid,mutexOwnerId); mutexThreadOwnerValid.setOwnerId(mutexOwnerId); threadOwnerValid = value; @@ -115,7 +148,7 @@ void BaseThread::setThreadOwnerValid(bool value) { bool BaseThread::getThreadOwnerValid() { //bool ret = false; - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + static string mutexOwnerId = CODE_AT_LINE; MutexSafeWrapper safeMutex(&mutexThreadOwnerValid,mutexOwnerId); //mutexThreadOwnerValid.setOwnerId(mutexOwnerId); bool ret = threadOwnerValid; @@ -131,7 +164,7 @@ void BaseThread::signalQuit() { void BaseThread::setQuitStatus(bool value) { if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] uniqueID [%s]\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str()); - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + static string mutexOwnerId = CODE_AT_LINE; MutexSafeWrapper safeMutex(&mutexQuit,mutexOwnerId); mutexQuit.setOwnerId(mutexOwnerId); quit = value; @@ -142,7 +175,7 @@ void BaseThread::setQuitStatus(bool value) { bool BaseThread::getQuitStatus() { //bool retval = false; - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + static string mutexOwnerId = CODE_AT_LINE; MutexSafeWrapper safeMutex(&mutexQuit,mutexOwnerId); //mutexQuit.setOwnerId(mutexOwnerId); bool retval = quit; @@ -153,7 +186,7 @@ bool BaseThread::getQuitStatus() { bool BaseThread::getHasBeginExecution() { //bool retval = false; - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + static string mutexOwnerId = CODE_AT_LINE; MutexSafeWrapper safeMutex(&mutexBeginExecution,mutexOwnerId); //mutexBeginExecution.setOwnerId(mutexOwnerId); bool retval = hasBeginExecution; @@ -165,7 +198,7 @@ bool BaseThread::getHasBeginExecution() { void BaseThread::setHasBeginExecution(bool value) { if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] uniqueID [%s]\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str()); - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + static string mutexOwnerId = CODE_AT_LINE; MutexSafeWrapper safeMutex(&mutexBeginExecution,mutexOwnerId); mutexBeginExecution.setOwnerId(mutexOwnerId); hasBeginExecution = value; @@ -177,7 +210,7 @@ void BaseThread::setHasBeginExecution(bool value) { bool BaseThread::getRunningStatus() { //bool retval = false; - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + static string mutexOwnerId = CODE_AT_LINE; MutexSafeWrapper safeMutex(&mutexRunning,mutexOwnerId); bool retval = running; safeMutex.ReleaseLock(); @@ -190,7 +223,7 @@ bool BaseThread::getRunningStatus() { } void BaseThread::setRunningStatus(bool value) { - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + static string mutexOwnerId = CODE_AT_LINE; MutexSafeWrapper safeMutex(&mutexRunning,mutexOwnerId); mutexRunning.setOwnerId(mutexOwnerId); running = value; @@ -201,7 +234,7 @@ void BaseThread::setRunningStatus(bool value) { } void BaseThread::setExecutingTask(bool value) { - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + static string mutexOwnerId = CODE_AT_LINE; MutexSafeWrapper safeMutex(&mutexExecutingTask,mutexOwnerId); mutexExecutingTask.setOwnerId(mutexOwnerId); executingTask = value; @@ -210,7 +243,7 @@ void BaseThread::setExecutingTask(bool value) { bool BaseThread::getExecutingTask() { //bool retval = false; - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + static string mutexOwnerId = CODE_AT_LINE; MutexSafeWrapper safeMutex(&mutexExecutingTask,mutexOwnerId); bool retval = executingTask; safeMutex.ReleaseLock(); @@ -220,7 +253,7 @@ bool BaseThread::getExecutingTask() { bool BaseThread::getDeleteSelfOnExecutionDone() { //bool retval = false; - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + static string mutexOwnerId = CODE_AT_LINE; MutexSafeWrapper safeMutex(&mutexDeleteSelfOnExecutionDone,mutexOwnerId); bool retval = deleteSelfOnExecutionDone; safeMutex.ReleaseLock(); @@ -229,7 +262,7 @@ bool BaseThread::getDeleteSelfOnExecutionDone() { } void BaseThread::setDeleteSelfOnExecutionDone(bool value) { - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + static string mutexOwnerId = CODE_AT_LINE; MutexSafeWrapper safeMutex(&mutexDeleteSelfOnExecutionDone,mutexOwnerId); mutexDeleteSelfOnExecutionDone.setOwnerId(mutexOwnerId); deleteSelfOnExecutionDone = value; diff --git a/source/shared_lib/sources/platform/common/simple_threads.cpp b/source/shared_lib/sources/platform/common/simple_threads.cpp index 350e7d67..404c7e53 100644 --- a/source/shared_lib/sources/platform/common/simple_threads.cpp +++ b/source/shared_lib/sources/platform/common/simple_threads.cpp @@ -316,7 +316,7 @@ void FileCRCPreCacheThread::addPendingTexture(Texture2D *texture) { if(texture == NULL) { return; } - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + static string mutexOwnerId = CODE_AT_LINE; MutexSafeWrapper safeMutex(&mutexPendingTextureList,mutexOwnerId); mutexPendingTextureList.setOwnerId(mutexOwnerId); pendingTextureList.push_back(texture); @@ -325,7 +325,7 @@ void FileCRCPreCacheThread::addPendingTexture(Texture2D *texture) { vector FileCRCPreCacheThread::getPendingTextureList(int maxTexturesToGet) { vector result; - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + static string mutexOwnerId = CODE_AT_LINE; MutexSafeWrapper safeMutex(&mutexPendingTextureList,mutexOwnerId); mutexPendingTextureList.setOwnerId(mutexOwnerId); unsigned int listCount = pendingTextureList.size(); @@ -359,13 +359,12 @@ SimpleTaskThread::SimpleTaskThread( SimpleTaskCallbackInterface *simpleTaskInter setTaskSignalled(false); - //static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + string mutexOwnerId = CODE_AT_LINE; MutexSafeWrapper safeMutex(&mutexLastExecuteTimestamp,mutexOwnerId); mutexLastExecuteTimestamp.setOwnerId(mutexOwnerId); lastExecuteTimestamp = time(NULL); - string mutexOwnerId1 = string(__FILE__) + string("_") + intToStr(__LINE__); + string mutexOwnerId1 = CODE_AT_LINE; MutexSafeWrapper safeMutex1(&mutexSimpleTaskInterfaceValid,mutexOwnerId1); if(this->simpleTaskInterfaceValid == true) { safeMutex1.ReleaseLock(); @@ -392,7 +391,7 @@ void SimpleTaskThread::cleanup() { this->overrideShutdownTask = NULL; } else if(this->simpleTaskInterface != NULL) { - string mutexOwnerId1 = string(__FILE__) + string("_") + intToStr(__LINE__); + string mutexOwnerId1 = CODE_AT_LINE; MutexSafeWrapper safeMutex1(&mutexSimpleTaskInterfaceValid,mutexOwnerId1); if(this->simpleTaskInterfaceValid == true) { safeMutex1.ReleaseLock(); @@ -407,9 +406,7 @@ void SimpleTaskThread::setOverrideShutdownTask(taskFunctionCallback *ptr) { } bool SimpleTaskThread::isThreadExecutionLagging() { - //bool result = false; - //static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + string mutexOwnerId = CODE_AT_LINE; MutexSafeWrapper safeMutex(&mutexLastExecuteTimestamp,mutexOwnerId); mutexLastExecuteTimestamp.setOwnerId(mutexOwnerId); bool result = (difftime(time(NULL),lastExecuteTimestamp) >= 5.0); @@ -430,13 +427,13 @@ bool SimpleTaskThread::canShutdown(bool deleteSelfIfShutdownDelayed) { } bool SimpleTaskThread::getSimpleTaskInterfaceValid() { - string mutexOwnerId1 = string(__FILE__) + string("_") + intToStr(__LINE__); + string mutexOwnerId1 = CODE_AT_LINE; MutexSafeWrapper safeMutex1(&mutexSimpleTaskInterfaceValid,mutexOwnerId1); return this->simpleTaskInterfaceValid; } void SimpleTaskThread::setSimpleTaskInterfaceValid(bool value) { - string mutexOwnerId1 = string(__FILE__) + string("_") + intToStr(__LINE__); + string mutexOwnerId1 = CODE_AT_LINE; MutexSafeWrapper safeMutex1(&mutexSimpleTaskInterfaceValid,mutexOwnerId1); this->simpleTaskInterfaceValid = value; @@ -460,7 +457,7 @@ void SimpleTaskThread::execute() { unsigned int idx = 0; for(;this->simpleTaskInterface != NULL;) { - string mutexOwnerId1 = string(__FILE__) + string("_") + intToStr(__LINE__); + string mutexOwnerId1 = CODE_AT_LINE; MutexSafeWrapper safeMutex1(&mutexSimpleTaskInterfaceValid,mutexOwnerId1); if(this->simpleTaskInterfaceValid == false) { break; @@ -486,8 +483,10 @@ void SimpleTaskThread::execute() { this->simpleTaskInterface->simpleTask(this); //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - //static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + if(getQuitStatus() == true) { + break; + } + string mutexOwnerId = CODE_AT_LINE; MutexSafeWrapper safeMutex(&mutexLastExecuteTimestamp,mutexOwnerId); mutexLastExecuteTimestamp.setOwnerId(mutexOwnerId); lastExecuteTimestamp = time(NULL); @@ -538,8 +537,7 @@ void SimpleTaskThread::execute() { } void SimpleTaskThread::setTaskSignalled(bool value) { - //static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + string mutexOwnerId = CODE_AT_LINE; MutexSafeWrapper safeMutex(&mutexTaskSignaller,mutexOwnerId); mutexTaskSignaller.setOwnerId(mutexOwnerId); taskSignalled = value; @@ -547,9 +545,7 @@ void SimpleTaskThread::setTaskSignalled(bool value) { } bool SimpleTaskThread::getTaskSignalled() { - //bool retval = false; - //static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + string mutexOwnerId = CODE_AT_LINE; MutexSafeWrapper safeMutex(&mutexTaskSignaller,mutexOwnerId); mutexTaskSignaller.setOwnerId(mutexOwnerId); bool retval = taskSignalled; @@ -564,7 +560,7 @@ LogFileThread::LogFileThread() : BaseThread() { uniqueID = "LogFileThread"; logList.clear(); lastSaveToDisk = time(NULL); - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + static string mutexOwnerId = CODE_AT_LINE; mutexLogList.setOwnerId(mutexOwnerId); } @@ -573,7 +569,7 @@ LogFileThread::~LogFileThread() { } void LogFileThread::addLogEntry(SystemFlags::DebugType type, string logEntry) { - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + static string mutexOwnerId = CODE_AT_LINE; MutexSafeWrapper safeMutex(&mutexLogList,mutexOwnerId); mutexLogList.setOwnerId(mutexOwnerId); LogFileEntry entry; @@ -652,7 +648,7 @@ void LogFileThread::execute() { } std::size_t LogFileThread::getLogEntryBufferCount() { - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + static string mutexOwnerId = CODE_AT_LINE; MutexSafeWrapper safeMutex(&mutexLogList,mutexOwnerId); mutexLogList.setOwnerId(mutexOwnerId); std::size_t logCount = logList.size(); @@ -672,7 +668,7 @@ bool LogFileThread::canShutdown(bool deleteSelfIfShutdownDelayed) { } void LogFileThread::saveToDisk(bool forceSaveAll,bool logListAlreadyLocked) { - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + static string mutexOwnerId = CODE_AT_LINE; MutexSafeWrapper safeMutex(NULL,mutexOwnerId); if(logListAlreadyLocked == false) { safeMutex.setMutex(&mutexLogList); diff --git a/source/shared_lib/sources/platform/sdl/thread.cpp b/source/shared_lib/sources/platform/sdl/thread.cpp index 15d592c8..330c47d6 100644 --- a/source/shared_lib/sources/platform/sdl/thread.cpp +++ b/source/shared_lib/sources/platform/sdl/thread.cpp @@ -103,6 +103,7 @@ public: BaseThread *base_thread = dynamic_cast(thread); if(base_thread != NULL && (base_thread->getRunningStatus() == true || base_thread->getExecutingTask() == true)) { + base_thread->signalQuit(); sleep(10); if(base_thread->getRunningStatus() == true || base_thread->getExecutingTask() == true) { @@ -127,7 +128,7 @@ public: // ===================================== // Threads // ===================================== -Thread::Thread() : thread(NULL), deleteAfterExecute(false) { +Thread::Thread() : thread(NULL), deleteAfterExecute(false), mutexthreadAccessor(new Mutex()) { addThreadToList(); } @@ -186,10 +187,12 @@ void Thread::shutdownThreads() { Thread::~Thread() { if(Thread::getEnableVerboseMode()) printf("In ~Thread Line: %d [%p] thread = %p\n",__LINE__,this,thread); + MutexSafeWrapper safeMutex(mutexthreadAccessor.get()); if(thread != NULL) { SDL_WaitThread(thread, NULL); thread = NULL; } + safeMutex.ReleaseLock(); if(Thread::getEnableVerboseMode()) printf("In ~Thread Line: %d [%p] thread = %p\n",__LINE__,this,thread); @@ -207,9 +210,16 @@ std::vector Thread::getThreadList() { } void Thread::start() { + MutexSafeWrapper safeMutex(mutexthreadAccessor.get()); + + BaseThread *base_thread = dynamic_cast(this); + if(base_thread) base_thread->setStarted(true); + thread = SDL_CreateThread(beginExecution, this); - assert(thread != NULL); + //assert(thread != NULL); if(thread == NULL) { + if(base_thread) base_thread->setStarted(false); + char szBuf[8096]=""; snprintf(szBuf,8095,"In [%s::%s Line: %d] thread == NULL",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); throw megaglest_runtime_error(szBuf); @@ -218,6 +228,11 @@ void Thread::start() { //printf("In Thread::start Line: %d [%p] thread = %p\n",__LINE__,this,thread); } +bool Thread::threadObjectValid() { + MutexSafeWrapper safeMutex(mutexthreadAccessor.get()); + return (thread != NULL); +} + void Thread::setPriority(Thread::Priority threadPriority) { NOIMPL; } @@ -235,11 +250,15 @@ int Thread::beginExecution(void* data) { ThreadGarbageCollector *garbage_collector = dynamic_cast(thread); if(Thread::getEnableVerboseMode()) printf("In Thread::execute Line: %d thread = %p base_thread = %p [%s]\n",__LINE__,thread,base_thread,(base_thread != NULL ? base_thread->getUniqueID().c_str() : "n/a")); - thread->execute(); + if(thread->threadObjectValid() == true) { + thread->execute(); + } if(Thread::getEnableVerboseMode()) printf("In Thread::execute Line: %d thread = %p base_thread = %p [%s]\n",__LINE__,thread,base_thread,(base_thread != NULL ? base_thread->getUniqueID().c_str() : "n/a")); - thread->queueAutoCleanThread(); + if(thread->threadObjectValid() == true) { + thread->queueAutoCleanThread(); + } if(Thread::getEnableVerboseMode()) printf("In Thread::execute Line: %d\n",__LINE__); @@ -309,6 +328,7 @@ void Thread::queueAutoCleanThread() { } void Thread::kill() { + MutexSafeWrapper safeMutex(mutexthreadAccessor.get()); SDL_KillThread(thread); thread = NULL; } @@ -438,8 +458,11 @@ Mutex::~Mutex() { void Mutex::p() { if(mutex == NULL) { + + string stack = PlatformExceptionHandler::getStackTrace(); + char szBuf[8096]=""; - snprintf(szBuf,8095,"In [%s::%s Line: %d] mutex == NULL refCount = %d owner [%s] deleteownerId [%s]",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,refCount,ownerId.c_str(),deleteownerId.c_str()); + snprintf(szBuf,8095,"In [%s::%s Line: %d] mutex == NULL refCount = %d owner [%s] deleteownerId [%s] stack: %s",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,refCount,ownerId.c_str(),deleteownerId.c_str(),stack.c_str()); throw megaglest_runtime_error(szBuf); } std::auto_ptr chronoLockPerf;