mirror of
https://github.com/glest/glest-source.git
synced 2025-08-15 21:04:00 +02:00
- attempt to have more clean shutdown of threads on game exit
This commit is contained in:
@@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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);
|
||||||
};
|
};
|
||||||
|
@@ -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);
|
||||||
|
@@ -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) {
|
||||||
|
@@ -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;
|
||||||
|
@@ -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) {
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user