- attempt to have more clean shutdown of threads on game exit

This commit is contained in:
Mark Vejvoda
2013-05-17 00:08:26 +00:00
parent 4bc007f239
commit 910bb8bc56
7 changed files with 196 additions and 23 deletions

View File

@@ -207,6 +207,7 @@ static void cleanupProcessObjects() {
//printf("Closing IRC CLient %d\n",__LINE__); //printf("Closing IRC CLient %d\n",__LINE__);
ircClient->disconnect(); ircClient->disconnect();
ircClient->signalQuit();
ircClient = NULL; ircClient = NULL;
/* /*
@@ -248,21 +249,39 @@ static void cleanupProcessObjects() {
//printf("Closing IRC CLient %d\n",__LINE__); //printf("Closing IRC CLient %d\n",__LINE__);
Thread::shutdownThreads();
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("start running threads = " MG_SIZE_T_SPECIFIER "\n",Thread::getThreadList().size()); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("start running threads = " MG_SIZE_T_SPECIFIER "\n",Thread::getThreadList().size());
time_t elapsed = time(NULL); time_t elapsed = time(NULL);
int lastLazyThreadDump = 0; int lastLazyThreadDump = 0;
for(;Thread::getThreadList().size() > 0 && for(;Thread::getThreadList().size() > 0 &&
difftime((long int)time(NULL),elapsed) <= 10;) { difftime((long int)time(NULL),elapsed) <= 10;) {
//sleep(0); //sleep(0);
if(difftime((long int)time(NULL),elapsed) > 1) { if(difftime((long int)time(NULL),elapsed) > 1) {
if(lastLazyThreadDump != (int)difftime((long int)time(NULL),elapsed)) { if(lastLazyThreadDump != (int)difftime((long int)time(NULL),elapsed)) {
lastLazyThreadDump = difftime((long int)time(NULL),elapsed); lastLazyThreadDump = difftime((long int)time(NULL),elapsed);
printf("Waiting for the following threads to exit [" MG_SIZE_T_SPECIFIER "]:\n",Thread::getThreadList().size()); printf("Waiting for the following threads to exit [" MG_SIZE_T_SPECIFIER "]:\n",Thread::getThreadList().size());
//std::auto_ptr<Thread> baseThreadTest(new FileCRCPreCacheThread());
for(int i = 0; i < Thread::getThreadList().size(); ++i) { for(int i = 0; i < Thread::getThreadList().size(); ++i) {
//Thread *thr = Thread::getThreadList()[i];
//printf("#1 Lagging thread typeid: %d [%s]\n,",typeid(thr),typeid(thr).name());
//BaseThread *baseThread = dynamic_cast<BaseThread *>(Thread::getThreadList()[i]);
BaseThread *baseThread = dynamic_cast<BaseThread *>(Thread::getThreadList()[i]); BaseThread *baseThread = dynamic_cast<BaseThread *>(Thread::getThreadList()[i]);
printf("Thread index: %d isBaseThread: %d, Name: [%s]\n",i,(baseThread != NULL),(baseThread != NULL ? baseThread->getUniqueID().c_str() : "<na>"));
printf("Thread index: %d ptr [%p] isBaseThread: %d, Name: [%s]\n",i,baseThread,(baseThread != NULL),(baseThread != NULL ? baseThread->getUniqueID().c_str() : "<na>"));
//printf("#2 Lagging thread typeid: %d [%s]\n,",typeid(baseThread),typeid(baseThread).name());
//if(baseThread != NULL && baseThread->getRunningStatus() == false) {
// baseThread->kill();
//}
//BaseThread *baseThread2 = dynamic_cast<BaseThread *>(baseThreadTest.get());
//printf("#3 Thread index: %d isBaseThread: %d, Name: [%s]\n",i,(baseThread2 != NULL),(baseThread2 != NULL ? baseThread2->getUniqueID().c_str() : "<na>"));
//printf("#3 Lagging thread typeid: %d [%s]\n,",typeid(baseThread2),typeid(baseThread2).name());
} }
} }
} }

View File

@@ -92,9 +92,13 @@ public:
Mutex * getMutexThreadObjectAccessor() { return &mutexThreadObjectAccessor; } Mutex * getMutexThreadObjectAccessor() { return &mutexThreadObjectAccessor; }
template <typename T> template <typename T>
T * getGenericData() { return genericData; } T * getGenericData() {
return genericData;
}
template <typename T> template <typename T>
void setGenericData(T *value) { genericData = value; } void setGenericData(T *value) {
genericData = value;
}
static bool isThreadDeleted(void *ptr); static bool isThreadDeleted(void *ptr);
}; };

View File

@@ -58,21 +58,30 @@ public:
private: private:
SDL_Thread* thread; SDL_Thread* thread;
bool deleteAfterExecute;
static Mutex mutexthreadList; static Mutex mutexthreadList;
static vector<Thread *> threadList; static vector<Thread *> threadList;
protected:
void addThreadToList();
void removeThreadFromList();
public: public:
Thread(); Thread();
virtual ~Thread(); virtual ~Thread();
static std::vector<Thread *> getThreadList(); static std::vector<Thread *> getThreadList();
static void shutdownThreads();
void setDeleteAfterExecute(bool value) { deleteAfterExecute = value; }
bool getDeleteAfterExecute() const { return deleteAfterExecute; }
void start(); void start();
virtual void execute()=0; virtual void execute()=0;
void setPriority(Thread::Priority threadPriority); void setPriority(Thread::Priority threadPriority);
void suspend(); void suspend();
void resume(); void resume();
void kill();
private: private:
static int beginExecution(void *param); static int beginExecution(void *param);

View File

@@ -24,7 +24,7 @@ namespace Shared { namespace PlatformCommon {
Mutex BaseThread::mutexMasterThreadList; Mutex BaseThread::mutexMasterThreadList;
std::map<void *,int> BaseThread::masterThreadList; std::map<void *,int> BaseThread::masterThreadList;
BaseThread::BaseThread() : Thread(), ptr(NULL) { BaseThread::BaseThread() : Thread(), ptr(NULL), genericData(NULL) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
ptr = this; ptr = this;
@@ -45,14 +45,23 @@ BaseThread::BaseThread() : Thread(), ptr(NULL) {
} }
BaseThread::~BaseThread() { 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()); 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(); 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); 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);
//printf("In ~BaseThread Line: %d uniqueID [%s]\n",__LINE__,uniqueID.c_str());
MutexSafeWrapper safeMutexMasterList(&mutexMasterThreadList); MutexSafeWrapper safeMutexMasterList(&mutexMasterThreadList);
//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] ret [%d] END\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str(),ret); 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);
//printf("In ~BaseThread Line: %d uniqueID [%s]\n",__LINE__,uniqueID.c_str());
if(masterThreadList.find(this) == masterThreadList.end()) { if(masterThreadList.find(this) == masterThreadList.end()) {
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); 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);
@@ -62,14 +71,21 @@ BaseThread::~BaseThread() {
} }
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); 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);
//printf("In ~BaseThread Line: %d uniqueID [%s]\n",__LINE__,uniqueID.c_str());
masterThreadList[this]--; masterThreadList[this]--;
if(masterThreadList[this] <= 0) { if(masterThreadList[this] <= 0) {
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); 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);
masterThreadList.erase(this); masterThreadList.erase(this);
} }
//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] ret [%d] END\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str(),ret); 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);
safeMutexMasterList.ReleaseLock(); safeMutexMasterList.ReleaseLock();
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); 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);
//printf("In ~BaseThread Line: %d uniqueID [%s] [%p]\n",__LINE__,uniqueID.c_str(),this);
} }
bool BaseThread::isThreadDeleted(void *ptr) { bool BaseThread::isThreadDeleted(void *ptr) {

View File

@@ -343,7 +343,9 @@ vector<Texture2D *> FileCRCPreCacheThread::getPendingTextureList(int maxTextures
SimpleTaskThread::SimpleTaskThread( SimpleTaskCallbackInterface *simpleTaskInterface, SimpleTaskThread::SimpleTaskThread( SimpleTaskCallbackInterface *simpleTaskInterface,
unsigned int executionCount, unsigned int executionCount,
unsigned int millisecsBetweenExecutions, unsigned int millisecsBetweenExecutions,
bool needTaskSignal) : BaseThread() { bool needTaskSignal) : BaseThread(),
simpleTaskInterface(NULL),
overrideShutdownTask(NULL) {
this->simpleTaskInterface = simpleTaskInterface; this->simpleTaskInterface = simpleTaskInterface;
this->executionCount = executionCount; this->executionCount = executionCount;
this->millisecsBetweenExecutions = millisecsBetweenExecutions; this->millisecsBetweenExecutions = millisecsBetweenExecutions;

View File

@@ -567,10 +567,10 @@ void IRCThread::signalQuit() {
MutexSafeWrapper safeMutex1(&mutexIRCSession,string(__FILE__) + "_" + intToStr(__LINE__)); MutexSafeWrapper safeMutex1(&mutexIRCSession,string(__FILE__) + "_" + intToStr(__LINE__));
irc_cmd_quit(ircSession, "MG Bot is closing!"); irc_cmd_quit(ircSession, "MG Bot is closing!");
safeMutex1.ReleaseLock(); safeMutex1.ReleaseLock();
BaseThread::signalQuit();
hasJoinedChannel = false; hasJoinedChannel = false;
} }
BaseThread::signalQuit();
#else #else
BaseThread::signalQuit(); BaseThread::signalQuit();
#endif #endif
@@ -802,22 +802,29 @@ void IRCThread::execute() {
return; return;
} }
//printf("In ~IRCThread Line: %d [%p]\n",__LINE__,this);
for(int iAttempts=1; for(int iAttempts=1;
this->getQuitStatus() == false && iAttempts <= 7; ++iAttempts) { this->getQuitStatus() == false && iAttempts <= 7; ++iAttempts) {
//if(irc_run(ircSession)) { //if(irc_run(ircSession)) {
int run_result = irc_run_session(ircSession); int run_result = irc_run_session(ircSession);
if(run_result && this->getQuitStatus() == false) { if(run_result && this->getQuitStatus() == false) {
//printf("In ~IRCThread Line: %d [%p]\n",__LINE__,this);
if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC Could not run the session: %s run_result = %d\n", irc_strerror (irc_errno(ircSession)), run_result); if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC Could not run the session: %s run_result = %d\n", irc_strerror (irc_errno(ircSession)), run_result);
printf ("===> IRC Could not run the session: %s run_result = %d\n", irc_strerror (irc_errno(ircSession)), run_result); printf ("===> IRC Could not run the session: %s run_result = %d\n", irc_strerror (irc_errno(ircSession)), run_result);
} }
} }
//printf("In ~IRCThread Line: %d [%p]\n",__LINE__,this);
#else #else
for(;this->getQuitStatus() == false;) { for(;this->getQuitStatus() == false;) {
sleep(50); sleep(50);
} }
#endif #endif
if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC exiting IRC CLient!\n"); if(SystemFlags::VERBOSE_MODE_ENABLED || IRCThread::debugEnabled) printf ("===> IRC exiting IRC CLient!\n");
//printf("In ~IRCThread Line: %d [%p]\n",__LINE__,this);
} }
catch(const exception &ex) { catch(const exception &ex) {
SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what()); SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
@@ -829,19 +836,27 @@ void IRCThread::execute() {
} }
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] IRC thread is exiting\n",__FILE__,__FUNCTION__,__LINE__); if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] IRC thread is exiting\n",__FILE__,__FUNCTION__,__LINE__);
//printf("In ~IRCThread Line: %d [%p]\n",__LINE__,this);
} }
//printf("In ~IRCThread Line: %d [%p]\n",__LINE__,this);
// Delete ourself when the thread is done (no other actions can happen after this // Delete ourself when the thread is done (no other actions can happen after this
// such as the mutex which modifies the running status of this method // such as the mutex which modifies the running status of this method
MutexSafeWrapper safeMutex(&mutexIRCCB,string(__FILE__) + "_" + intToStr(__LINE__)); MutexSafeWrapper safeMutex(&mutexIRCCB,string(__FILE__) + "_" + intToStr(__LINE__));
IRCCallbackInterface *cb = getCallbackObj(false); IRCCallbackInterface *cb = getCallbackObj(false);
if(cb != NULL) { if(cb != NULL) {
//printf("In ~IRCThread Line: %d [%p]\n",__LINE__,this);
cb->IRC_CallbackEvent(IRC_evt_exitThread, NULL, NULL, 0); cb->IRC_CallbackEvent(IRC_evt_exitThread, NULL, NULL, 0);
} }
safeMutex.ReleaseLock(); safeMutex.ReleaseLock();
//printf("In ~IRCThread Line: %d [%p]\n",__LINE__,this);
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In IRCThread() calling delete ...\n"); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In IRCThread() calling delete ...\n");
delete this;
//printf("In ~IRCThread Line: %d [%p]\n",__LINE__,this);
//delete this;
setDeleteAfterExecute(true);
} }
int IRCThread::irc_run_session(irc_session_t * session) { int IRCThread::irc_run_session(irc_session_t * session) {
@@ -899,12 +914,18 @@ int IRCThread::irc_run_session(irc_session_t * session) {
} }
IRCThread::~IRCThread() { IRCThread::~IRCThread() {
//printf("In ~IRCThread Line: %d [%p]\n",__LINE__,this);
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In ~IRCThread() ...\n"); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In ~IRCThread() ...\n");
if(IRCThread::globalCacheContainerName != NULL) { if(IRCThread::globalCacheContainerName != NULL) {
//printf("In ~IRCThread Line: %d [%p]\n",__LINE__,this);
IRCThread * &ircClient = CacheManager::getCachedItem< IRCThread * >(IRCThread::globalCacheContainerName); IRCThread * &ircClient = CacheManager::getCachedItem< IRCThread * >(IRCThread::globalCacheContainerName);
ircClient = NULL; ircClient = NULL;
} }
//printf("In ~IRCThread Line: %d [%p]\n",__LINE__,this);
} }
void normalizeNick(char *nick) { void normalizeNick(char *nick) {

View File

@@ -16,6 +16,8 @@
#include <algorithm> #include <algorithm>
#include "platform_util.h" #include "platform_util.h"
#include "platform_common.h" #include "platform_common.h"
#include "base_thread.h"
#include "time.h"
#include <memory> #include <memory>
using namespace std; using namespace std;
@@ -28,31 +30,112 @@ vector<Thread *> Thread::threadList;
auto_ptr<Mutex> Mutex::mutexMutexList(new Mutex(CODE_AT_LINE)); auto_ptr<Mutex> Mutex::mutexMutexList(new Mutex(CODE_AT_LINE));
vector<Mutex *> Mutex::mutexList; vector<Mutex *> Mutex::mutexList;
class ThreadAutoCleanup : public BaseThread
{
protected:
Mutex mutexPendingCleanupList;
vector<Thread *> pendingCleanupList;
bool cleanupPendingThreads() {
MutexSafeWrapper safeMutex(&mutexPendingCleanupList);
if(pendingCleanupList.empty() == false) {
for(unsigned int index = 0; index < pendingCleanupList.size(); ++index) {
delete pendingCleanupList[index];
}
pendingCleanupList.clear();
return true;
}
return false;
}
public:
ThreadAutoCleanup() : BaseThread() {
removeThreadFromList();
}
virtual ~ThreadAutoCleanup() {
}
virtual void execute() {
RunningStatusSafeWrapper runningStatus(this);
for(;getQuitStatus() == false;) {
if(cleanupPendingThreads() == false) {
if(getQuitStatus() == false) {
sleep(200);
}
}
}
cleanupPendingThreads();
}
void addThread(Thread *thread) {
MutexSafeWrapper safeMutex(&mutexPendingCleanupList);
pendingCleanupList.push_back(thread);
safeMutex.ReleaseLock();
}
};
static auto_ptr<ThreadAutoCleanup> cleanupThread;
// ===================================== // =====================================
// Threads // Threads
// ===================================== // =====================================
Thread::Thread() { Thread::Thread() : thread(NULL), deleteAfterExecute(false) {
addThreadToList();
}
void Thread::addThreadToList() {
MutexSafeWrapper safeMutex(&Thread::mutexthreadList); MutexSafeWrapper safeMutex(&Thread::mutexthreadList);
Thread::threadList.push_back(this); Thread::threadList.push_back(this);
safeMutex.ReleaseLock(); safeMutex.ReleaseLock();
thread = NULL; }
void Thread::removeThreadFromList() {
MutexSafeWrapper safeMutex(&Thread::mutexthreadList);
std::vector<Thread *>::iterator iterFind = std::find(Thread::threadList.begin(),Thread::threadList.end(),this);
if(iterFind == Thread::threadList.end()) {
if(this != cleanupThread.get()) {
char szBuf[8096]="";
snprintf(szBuf,8095,"In [%s::%s Line: %d] iterFind == Thread::threadList.end()",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
throw megaglest_runtime_error(szBuf);
}
}
else {
Thread::threadList.erase(iterFind);
}
safeMutex.ReleaseLock();
}
void Thread::shutdownThreads() {
MutexSafeWrapper safeMutex(&Thread::mutexthreadList);
for(unsigned int index = 0; index < Thread::threadList.size(); ++index) {
BaseThread *thread = dynamic_cast<BaseThread *>(Thread::threadList[index]);
if(thread && thread->getRunningStatus() == true) {
thread->signalQuit();
}
}
safeMutex.ReleaseLock();
if(cleanupThread.get() != 0) {
sleep(0);
cleanupThread->signalQuit();
time_t elapsed = time(NULL);
for(;cleanupThread->getRunningStatus() == true &&
difftime((long int)time(NULL),elapsed) <= 5;) {
sleep(100);
}
cleanupThread.reset(0);
}
} }
Thread::~Thread() { Thread::~Thread() {
//printf("In ~Thread Line: %d [%p] thread = %p\n",__LINE__,this,thread);
if(thread != NULL) { if(thread != NULL) {
SDL_WaitThread(thread, NULL); SDL_WaitThread(thread, NULL);
thread = NULL; thread = NULL;
} }
MutexSafeWrapper safeMutex(&Thread::mutexthreadList); //printf("In ~Thread Line: %d [%p] thread = %p\n",__LINE__,this,thread);
std::vector<Thread *>::iterator iterFind = std::find(Thread::threadList.begin(),Thread::threadList.end(),this);
if(iterFind == Thread::threadList.end()) { removeThreadFromList();
char szBuf[8096]="";
snprintf(szBuf,8095,"In [%s::%s Line: %d] iterFind == Thread::threadList.end()",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); //printf("In ~Thread Line: %d [%p] thread = %p\n",__LINE__,this,thread);
throw megaglest_runtime_error(szBuf);
}
Thread::threadList.erase(iterFind);
safeMutex.ReleaseLock();
} }
std::vector<Thread *> Thread::getThreadList() { std::vector<Thread *> Thread::getThreadList() {
@@ -71,6 +154,8 @@ void Thread::start() {
snprintf(szBuf,8095,"In [%s::%s Line: %d] thread == NULL",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); snprintf(szBuf,8095,"In [%s::%s Line: %d] thread == NULL",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
throw megaglest_runtime_error(szBuf); throw megaglest_runtime_error(szBuf);
} }
//printf("In Thread::start Line: %d [%p] thread = %p\n",__LINE__,this,thread);
} }
void Thread::setPriority(Thread::Priority threadPriority) { void Thread::setPriority(Thread::Priority threadPriority) {
@@ -85,10 +170,27 @@ int Thread::beginExecution(void* data) {
snprintf(szBuf,8095,"In [%s::%s Line: %d] thread == NULL",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); snprintf(szBuf,8095,"In [%s::%s Line: %d] thread == NULL",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
throw megaglest_runtime_error(szBuf); throw megaglest_runtime_error(szBuf);
} }
//printf("In Thread::execute Line: %d thread = %p\n",__LINE__,thread);
thread->execute(); thread->execute();
//printf("In Thread::execute Line: %d thread = %p\n",__LINE__,thread);
if(thread->deleteAfterExecute == true) {
if(cleanupThread.get() == NULL) {
cleanupThread.reset(new ThreadAutoCleanup());
cleanupThread->start();
}
cleanupThread->addThread(thread);
}
return 0; return 0;
} }
void Thread::kill() {
SDL_KillThread(thread);
thread = NULL;
}
void Thread::suspend() { void Thread::suspend() {
NOIMPL; NOIMPL;
} }