- bugfix for unit selection segfault on game exit

- added thread hardening to try to ensure we never try to delete a thread more than once.
This commit is contained in:
Mark Vejvoda
2012-04-12 20:43:19 +00:00
parent 76c3fa1949
commit 9aca26a0f0
5 changed files with 73 additions and 11 deletions

View File

@@ -20,9 +20,17 @@ using namespace Shared::Util;
namespace Shared { namespace PlatformCommon {
BaseThread::BaseThread() : Thread() {
Mutex BaseThread::mutexMasterThreadList;
std::map<void *,int> 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;
}
}

View File

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