- updated thread handling slightly in menus to make things more stable

This commit is contained in:
Mark Vejvoda 2010-12-05 01:52:38 +00:00
parent f545edad68
commit 7872e980e1
8 changed files with 145 additions and 43 deletions

View File

@ -527,7 +527,10 @@ MenuStateCustomGame::~MenuStateCustomGame() {
needToRepublishToMasterserver = false;
//BaseThread::shutdownAndWait(publishToMasterserverThread);
delete publishToMasterserverThread;
if(publishToMasterserverThread != NULL &&
publishToMasterserverThread->shutdownAndWait() == true) {
delete publishToMasterserverThread;
}
publishToMasterserverThread = NULL;
publishToMasterserverThreadInDeletion = false;
safeMutexPtr.ReleaseLock();
@ -556,7 +559,10 @@ void MenuStateCustomGame::returnToParentMenu(){
bool returnToMasterServerMenu = parentMenuIsMs;
//BaseThread::shutdownAndWait(publishToMasterserverThread);
delete publishToMasterserverThread;
if(publishToMasterserverThread != NULL &&
publishToMasterserverThread->shutdownAndWait() == true) {
delete publishToMasterserverThread;
}
publishToMasterserverThread = NULL;
publishToMasterserverThreadInDeletion = false;
safeMutexPtr.ReleaseLock();
@ -605,7 +611,10 @@ void MenuStateCustomGame::mouseClick(int x, int y, MouseButton mouseButton){
MutexSafeWrapper safeMutexPtr(&publishToMasterserverThreadPtrChangeAccessor);
publishToMasterserverThreadInDeletion = true;
//BaseThread::shutdownAndWait(publishToMasterserverThread);
delete publishToMasterserverThread;
if(publishToMasterserverThread != NULL &&
publishToMasterserverThread->shutdownAndWait() == true) {
delete publishToMasterserverThread;
}
publishToMasterserverThread = NULL;
publishToMasterserverThreadInDeletion = false;
safeMutexPtr.ReleaseLock();
@ -1115,7 +1124,10 @@ void MenuStateCustomGame::PlayNow() {
MutexSafeWrapper safeMutexPtr(&publishToMasterserverThreadPtrChangeAccessor);
publishToMasterserverThreadInDeletion = true;
//BaseThread::shutdownAndWait(publishToMasterserverThread);
delete publishToMasterserverThread;
if(publishToMasterserverThread != NULL &&
publishToMasterserverThread->shutdownAndWait() == true) {
delete publishToMasterserverThread;
}
publishToMasterserverThread = NULL;
publishToMasterserverThreadInDeletion = false;
safeMutexPtr.ReleaseLock();
@ -1837,8 +1849,16 @@ void MenuStateCustomGame::publishToMasterserver()
void MenuStateCustomGame::simpleTask() {
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
if(publishToMasterserverThreadInDeletion == true) {
return;
}
if( publishToMasterserverThread == NULL ||
publishToMasterserverThread->getQuitStatus() == true) {
return;
}
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
MutexSafeWrapper safeMutex(&masterServerThreadAccessor);
bool republish = (needToRepublishToMasterserver == true && publishToServerInfo.size() != 0);
needToRepublishToMasterserver = false;

View File

@ -332,7 +332,6 @@ MenuStateMasterserver::MenuStateMasterserver(Program *program, MainMenu *mainMen
NetworkManager::getInstance().end();
NetworkManager::getInstance().init(nrClient);
//updateServerInfo();
// write hint to console:
Config &configKeys = Config::getInstance(std::pair<ConfigType,ConfigType>(cfgMainKeys,cfgUserKeys));
@ -365,7 +364,10 @@ MenuStateMasterserver::~MenuStateMasterserver() {
//BaseThread::shutdownAndWait(updateFromMasterserverThread);
masterServerThreadInDeletion = true;
delete updateFromMasterserverThread;
if(updateFromMasterserverThread != NULL &&
updateFromMasterserverThread->shutdownAndWait() == true) {
delete updateFromMasterserverThread;
}
updateFromMasterserverThread = NULL;
masterServerThreadInDeletion = false;
safeMutexPtr.ReleaseLock();
@ -411,7 +413,6 @@ void MenuStateMasterserver::mouseClick(int x, int y, MouseButton mouseButton){
MutexSafeWrapper safeMutex(&masterServerThreadAccessor);
soundRenderer.playFx(coreData.getClickSoundB());
//updateServerInfo();
needUpdateFromServer = true;
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
@ -425,7 +426,10 @@ void MenuStateMasterserver::mouseClick(int x, int y, MouseButton mouseButton){
//BaseThread::shutdownAndWait(updateFromMasterserverThread);
MutexSafeWrapper safeMutexPtr(&masterServerThreadPtrChangeAccessor);
masterServerThreadInDeletion = true;
delete updateFromMasterserverThread;
if(updateFromMasterserverThread != NULL &&
updateFromMasterserverThread->shutdownAndWait() == true) {
delete updateFromMasterserverThread;
}
updateFromMasterserverThread = NULL;
masterServerThreadInDeletion = false;
safeMutexPtr.ReleaseLock();
@ -451,7 +455,10 @@ void MenuStateMasterserver::mouseClick(int x, int y, MouseButton mouseButton){
//BaseThread::shutdownAndWait(updateFromMasterserverThread);
MutexSafeWrapper safeMutexPtr(&masterServerThreadPtrChangeAccessor);
masterServerThreadInDeletion = true;
delete updateFromMasterserverThread;
if(updateFromMasterserverThread != NULL &&
updateFromMasterserverThread->shutdownAndWait() == true) {
delete updateFromMasterserverThread;
}
updateFromMasterserverThread = NULL;
masterServerThreadInDeletion = false;
safeMutexPtr.ReleaseLock();
@ -481,8 +488,10 @@ void MenuStateMasterserver::mouseClick(int x, int y, MouseButton mouseButton){
MutexSafeWrapper safeMutexPtr(&masterServerThreadPtrChangeAccessor);
masterServerThreadInDeletion = true;
BaseThread::shutdownAndWait(updateFromMasterserverThread);
delete updateFromMasterserverThread;
if(updateFromMasterserverThread != NULL &&
updateFromMasterserverThread->shutdownAndWait() == true) {
delete updateFromMasterserverThread;
}
updateFromMasterserverThread = NULL;
masterServerThreadInDeletion = false;
safeMutexPtr.ReleaseLock();
@ -597,6 +606,10 @@ void MenuStateMasterserver::update(){
}
void MenuStateMasterserver::simpleTask() {
if(masterServerThreadInDeletion == true) {
return;
}
if( updateFromMasterserverThread == NULL ||
updateFromMasterserverThread->getQuitStatus() == true) {
return;

View File

@ -387,6 +387,8 @@ void NetworkMessageCommandList::send(Socket* socket) const{
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] index = %d, sent networkCommand [%s]\n",
__FILE__,__FUNCTION__,__LINE__,idx, cmd.toString().c_str());
}
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] END of loop, nmtCommandList, frameCount = %d, data.header.commandCount = %d, data.header.messageType = %d\n",__FILE__,__FUNCTION__,__LINE__,data.header.frameCount,data.header.commandCount,data.header.messageType);
}
}
}

View File

@ -51,8 +51,9 @@ public:
virtual bool getHasBeginExecution();
virtual void setHasBeginExecution(bool value);
static void shutdownAndWait(BaseThread *ppThread);
virtual void shutdownAndWait();
static bool shutdownAndWait(BaseThread *ppThread);
virtual bool shutdownAndWait();
virtual bool canShutdown() { return true; }
void setUniqueID(string value) { uniqueID = value; }
string getUniqueID() { return uniqueID; }

View File

@ -61,6 +61,9 @@ protected:
bool taskSignalled;
bool needTaskSignal;
Mutex mutexExecutingTask;
bool executingTask;
public:
SimpleTaskThread();
SimpleTaskThread(SimpleTaskCallbackInterface *simpleTaskInterface,
@ -68,8 +71,12 @@ public:
unsigned int millisecsBetweenExecutions=0,
bool needTaskSignal = false);
virtual void execute();
virtual bool canShutdown();
void setTaskSignalled(bool value);
bool getTaskSignalled();
void setExecutingTask(bool value);
bool getExecutingTask();
};
}}//end namespace

View File

@ -33,8 +33,8 @@ BaseThread::BaseThread() : Thread() {
BaseThread::~BaseThread() {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] uniqueID [%s]\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str());
shutdownAndWait();
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] uniqueID [%s] END\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str());
bool ret = shutdownAndWait();
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] uniqueID [%s] ret [%d] END\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str(),ret);
}
void BaseThread::signalQuit() {
@ -117,32 +117,50 @@ void BaseThread::setRunningStatus(bool value) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] uniqueID [%s]\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str());
}
void BaseThread::shutdownAndWait(BaseThread *pThread) {
bool BaseThread::shutdownAndWait(BaseThread *pThread) {
bool ret = false;
if(pThread != NULL) {
ret = pThread->shutdownAndWait();
}
return ret;
}
bool BaseThread::shutdownAndWait() {
bool ret = true;
BaseThread *pThread = this;
string uniqueID = (pThread != NULL ? pThread->getUniqueID() : "?");
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] uniqueID [%s]\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str());
if(pThread != NULL && pThread->getRunningStatus() == true) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] uniqueID [%s]\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str());
if(pThread != NULL) {
if(pThread->getRunningStatus() == true) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] uniqueID [%s]\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str());
pThread->signalQuit();
//sleep(0);
pThread->signalQuit();
//sleep(0);
ret = false;
for( time_t elapsed = time(NULL); difftime(time(NULL),elapsed) <= 7; ) {
if(pThread->getRunningStatus() == false) {
break;
int maxWaitSeconds = 7;
if(pThread->canShutdown() == false) {
maxWaitSeconds = 3;
}
sleep(1);
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
for( time_t elapsed = time(NULL); difftime(time(NULL),elapsed) <= maxWaitSeconds; ) {
if(pThread->getRunningStatus() == false) {
ret = true;
break;
}
sleep(0);
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
//sleep(0);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] uniqueID [%s]\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str());
}
//sleep(0);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] uniqueID [%s]\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str());
}
//sleep(0);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] uniqueID [%s] END\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str());
}
void BaseThread::shutdownAndWait() {
BaseThread::shutdownAndWait(this);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] uniqueID [%s] ret [%d] END\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str(),ret);
return ret;
}
}}//end namespace

View File

@ -83,6 +83,11 @@ SimpleTaskThread::SimpleTaskThread( SimpleTaskCallbackInterface *simpleTaskInter
this->millisecsBetweenExecutions = millisecsBetweenExecutions;
this->needTaskSignal = needTaskSignal;
setTaskSignalled(false);
setExecutingTask(false);
}
bool SimpleTaskThread::canShutdown() {
return (getExecutingTask() == false);
}
void SimpleTaskThread::execute() {
@ -97,7 +102,6 @@ void SimpleTaskThread::execute() {
unsigned int idx = 0;
for(;this->simpleTaskInterface != NULL;) {
bool runTask = true;
if(needTaskSignal == true) {
runTask = getTaskSignalled();
@ -113,7 +117,15 @@ void SimpleTaskThread::execute() {
else if(runTask == true) {
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] uniqueID [%s]\n",__FILE__,__FUNCTION__,__LINE__,this->getUniqueID().c_str());
if(getQuitStatus() == false) {
this->simpleTaskInterface->simpleTask();
try {
setExecutingTask(true);
this->simpleTaskInterface->simpleTask();
setExecutingTask(false);
}
catch(const exception &ex) {
setExecutingTask(false);
throw runtime_error(ex.what());
}
}
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] uniqueID [%s]\n",__FILE__,__FUNCTION__,__LINE__,this->getUniqueID().c_str());
}
@ -173,4 +185,19 @@ bool SimpleTaskThread::getTaskSignalled() {
return retval;
}
void SimpleTaskThread::setExecutingTask(bool value) {
MutexSafeWrapper safeMutex(&mutexExecutingTask);
executingTask = value;
safeMutex.ReleaseLock();
}
bool SimpleTaskThread::getExecutingTask() {
bool retval = false;
MutexSafeWrapper safeMutex(&mutexExecutingTask);
retval = executingTask;
safeMutex.ReleaseLock();
return retval;
}
}}//end namespace

View File

@ -1017,6 +1017,7 @@ int Socket::send(const void *data, int dataSize) {
attemptCount++;
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] attemptCount = %d\n",__FILE__,__FUNCTION__,__LINE__,attemptCount);
sleep(0);
//if(Socket::isWritable(true) == true) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] attemptCount = %d, sock = %d, dataSize = %d, data = %p\n",__FILE__,__FUNCTION__,__LINE__,attemptCount,sock,dataSize,data);
#ifdef __APPLE__
@ -1044,6 +1045,7 @@ int Socket::send(const void *data, int dataSize) {
attemptCount++;
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] attemptCount = %d, totalBytesSent = %d\n",__FILE__,__FUNCTION__,__LINE__,attemptCount,totalBytesSent);
sleep(0);
//if(bytesSent > 0 || Socket::isWritable(true) == true) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] attemptCount = %d, sock = %d, dataSize = %d, data = %p\n",__FILE__,__FUNCTION__,__LINE__,attemptCount,sock,dataSize,data);
@ -1101,7 +1103,8 @@ int Socket::receive(void *data, int dataSize)
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] #1 EAGAIN during receive, trying again...\n",__FILE__,__FUNCTION__,__LINE__);
time_t tStartTimer = time(NULL);
while((bytesReceived < 0 && getLastSocketError() == PLATFORM_SOCKET_TRY_AGAIN) && (difftime(time(NULL),tStartTimer) <= 5)) {
while((bytesReceived < 0 && getLastSocketError() == PLATFORM_SOCKET_TRY_AGAIN) &&
(difftime(time(NULL),tStartTimer) <= 5)) {
if(Socket::isReadable() == true) {
MutexSafeWrapper safeMutex(&dataSynchAccessor);
bytesReceived = recv(sock, reinterpret_cast<char*>(data), dataSize, 0);
@ -1137,7 +1140,8 @@ int Socket::peek(void *data, int dataSize){
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] #1 EAGAIN during peek, trying again...\n",__FILE__,__FUNCTION__,__LINE__);
time_t tStartTimer = time(NULL);
while((err < 0 && getLastSocketError() == PLATFORM_SOCKET_TRY_AGAIN) && (difftime(time(NULL),tStartTimer) <= 5)) {
while((err < 0 && getLastSocketError() == PLATFORM_SOCKET_TRY_AGAIN) &&
(difftime(time(NULL),tStartTimer) <= 5)) {
if(Socket::isReadable() == true) {
//MutexSafeWrapper safeMutex(&dataSynchAccessor);
err = recv(sock, reinterpret_cast<char*>(data), dataSize, MSG_PEEK);
@ -1220,35 +1224,45 @@ bool Socket::isWritable(bool waitOnDelayedResponse) {
FD_ZERO(&set);
FD_SET(sock, &set);
time_t maxElapsedCheck = time(NULL);
const int MAX_CHECK_WAIT_SECONDS = 5;
bool result = false;
do {
if(difftime(time(NULL),maxElapsedCheck) >= MAX_CHECK_WAIT_SECONDS) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s Line: %d] max timeout waited during writable check\n",__FILE__,__FUNCTION__,__LINE__);
break;
}
int i = 0;
{
//MutexSafeWrapper safeMutex(&dataSynchAccessor);
i = select((int)sock + 1, NULL, &set, NULL, &tv);
}
if(i < 0 ) {
if(difftime(time(NULL),lastDebugEvent) >= 1) {
//if(difftime(time(NULL),lastDebugEvent) >= 1) {
lastDebugEvent = time(NULL);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s] error while selecting socket data, err = %d, error = %s\n",__FILE__,__FUNCTION__,i,getLastSocketErrorFormattedText().c_str());
}
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s Line: %d] error while selecting socket data, err = %d, error = %s\n",__FILE__,__FUNCTION__,__LINE__,i,getLastSocketErrorFormattedText().c_str());
//}
waitOnDelayedResponse = false;
//throwException("Error selecting socket");
}
else if(i == 0) {
if(difftime(time(NULL),lastDebugEvent) >= 1) {
//if(difftime(time(NULL),lastDebugEvent) >= 1) {
lastDebugEvent = time(NULL);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s] TIMEOUT while selecting socket data, err = %d, error = %s\n",__FILE__,__FUNCTION__,i,getLastSocketErrorFormattedText().c_str());
}
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s Line: %d] TIMEOUT while selecting socket data, err = %d, error = %s\n",__FILE__,__FUNCTION__,__LINE__,i,getLastSocketErrorFormattedText().c_str());
//}
if(waitOnDelayedResponse == false) {
result = true;
break;
}
}
else {
result = true;
break;
}
} while(waitOnDelayedResponse == true && result == false);