bugfix for shutdown of threads and garbage collection.

This commit is contained in:
Mark Vejvoda 2013-06-22 03:36:18 +00:00
parent 76ee030e93
commit bb14d4cc1e
5 changed files with 102 additions and 40 deletions

View File

@ -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);

View File

@ -58,6 +58,9 @@ public:
private:
SDL_Thread* thread;
std::auto_ptr<Mutex> mutexthreadAccessor;
bool threadObjectValid();
bool deleteAfterExecute;
static Mutex mutexthreadList;
static vector<Thread *> threadList;

View File

@ -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<BaseThread *>(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;

View File

@ -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<Texture2D *> FileCRCPreCacheThread::getPendingTextureList(int maxTexturesToGet) {
vector<Texture2D *> 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);

View File

@ -103,6 +103,7 @@ public:
BaseThread *base_thread = dynamic_cast<BaseThread *>(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 *> Thread::getThreadList() {
}
void Thread::start() {
MutexSafeWrapper safeMutex(mutexthreadAccessor.get());
BaseThread *base_thread = dynamic_cast<BaseThread *>(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<ThreadGarbageCollector *>(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<Chrono> chronoLockPerf;