- bugfix for mutex deadlock

This commit is contained in:
Mark Vejvoda 2010-06-18 18:47:20 +00:00
parent 7fb136890c
commit 82f412453e
7 changed files with 89 additions and 52 deletions

View File

@ -179,6 +179,7 @@ MenuStateMasterserver::MenuStateMasterserver(Program *program, MainMenu *mainMen
needUpdateFromServer = true;
updateFromMasterserverThread = new SimpleTaskThread(this,0,100);
updateFromMasterserverThread->setUniqueID(__FILE__);
updateFromMasterserverThread->start();
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
@ -187,16 +188,21 @@ MenuStateMasterserver::MenuStateMasterserver(Program *program, MainMenu *mainMen
MenuStateMasterserver::~MenuStateMasterserver() {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
MutexSafeWrapper safeMutex(&masterServerThreadAccessor);
needUpdateFromServer = false;
clearServerLines();
safeMutex.ReleaseLock();
if(updateFromMasterserverThread != NULL) {
MutexSafeWrapper safeMutex(&masterServerThreadAccessor);
needUpdateFromServer = false;
safeMutex.ReleaseLock();
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
//BaseThread::shutdownAndWait(updateFromMasterserverThread);
delete updateFromMasterserverThread;
updateFromMasterserverThread = NULL;
}
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
//BaseThread::shutdownAndWait(updateFromMasterserverThread);
delete updateFromMasterserverThread;
updateFromMasterserverThread = NULL;
clearServerLines();
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
@ -278,11 +284,20 @@ void MenuStateMasterserver::mouseClick(int x, int y, MouseButton mouseButton){
else {
MutexSafeWrapper safeMutex(&masterServerThreadAccessor);
for(int i=0; i<serverLines.size(); ++i){
if(serverLines[i]->buttonMouseClick(x, y)){
if(serverLines[i]->buttonMouseClick(x, y)) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
soundRenderer.playFx(coreData.getClickSoundB());
string connectServerIP = serverLines[i]->getMasterServerInfo()->getIpAddress();
safeMutex.ReleaseLock();
connectToServer(connectServerIP);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
safeMutex.ReleaseLock();
BaseThread::shutdownAndWait(updateFromMasterserverThread);
delete updateFromMasterserverThread;
updateFromMasterserverThread = NULL;
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
mainMenu->setState(new MenuStateConnectedGame(program, mainMenu,jmMasterserver));
break;
}
}
@ -354,16 +369,18 @@ void MenuStateMasterserver::update(){
}
void MenuStateMasterserver::simpleTask() {
if( updateFromMasterserverThread == NULL ||
updateFromMasterserverThread->getQuitStatus() == true) {
return;
}
MutexSafeWrapper safeMutex(&masterServerThreadAccessor);
if(needUpdateFromServer == true) {
safeMutex.ReleaseLock();
updateServerInfo();
}
}
void MenuStateMasterserver::updateServerInfo() {
try {
MutexSafeWrapper safeMutex(&masterServerThreadAccessor);
needUpdateFromServer = false;
int numberOfOldServerLines=serverLines.size();
@ -420,19 +437,15 @@ void MenuStateMasterserver::updateServerInfo() {
}
catch(const exception &e){
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] Line: %d, error [%s]\n",__FILE__,__FUNCTION__,__LINE__,e.what());
MutexSafeWrapper safeMutex(&masterServerThreadAccessor);
threadedErrorMsg = e.what();
}
}
void MenuStateMasterserver::connectToServer(string ipString)
bool MenuStateMasterserver::connectToServer(string ipString)
{
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] START ipString='%s'\n",__FILE__,__FUNCTION__,ipString.c_str());
MutexSafeWrapper safeMutex(&masterServerThreadAccessor);
ClientInterface* clientInterface= NetworkManager::getInstance().getClientInterface();
Config& config= Config::getInstance();
Ip serverIp(ipString);
@ -448,27 +461,21 @@ void MenuStateMasterserver::connectToServer(string ipString)
mainMessageBoxState=1;
Lang &lang= Lang::getInstance();
showMessageBox(lang.get("Couldnt connect"), lang.get("Connection failed"), false);
return;
return false;
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] connection failed\n",__FILE__,__FUNCTION__);
}
else
{
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] connected ro [%s]\n",__FILE__,__FUNCTION__,serverIp.getString().c_str());
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] connected to [%s]\n",__FILE__,__FUNCTION__,serverIp.getString().c_str());
//save server ip
//config.setString("ServerIp", serverIp.getString());
//config.save();
//BaseThread::shutdownAndWait(updateFromMasterserverThread);
delete updateFromMasterserverThread;
updateFromMasterserverThread = NULL;
safeMutex.ReleaseLock();
mainMenu->setState(new MenuStateConnectedGame(program, mainMenu,jmMasterserver));
return true;
}
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] END\n",__FILE__,__FUNCTION__);
}
void MenuStateMasterserver::showMessageBox(const string &text, const string &header, bool toggle){

View File

@ -103,7 +103,7 @@ public:
private:
void showMessageBox(const string &text, const string &header, bool toggle);
void connectToServer(string ipString);
bool connectToServer(string ipString);
void clearServerLines();
void updateServerInfo();

View File

@ -114,7 +114,8 @@ void ClientInterface::update()
int lastSendElapsed = difftime(time(NULL),lastNetworkCommandListSendTime);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] lastSendElapsed = %d\n",__FILE__,__FUNCTION__,__LINE__,lastSendElapsed);
if(networkMessageCommandList.getCommandCount() > 0 || lastSendElapsed >= ClientInterface::maxNetworkCommandListSendTimeWait) {
if(networkMessageCommandList.getCommandCount() > 0 ||
(lastNetworkCommandListSendTime > 0 && lastSendElapsed >= ClientInterface::maxNetworkCommandListSendTimeWait)) {
sendMessage(&networkMessageCommandList);
lastNetworkCommandListSendTime = time(NULL);
}

View File

@ -13,8 +13,10 @@
#define _SHARED_PLATFORMCOMMON_BASETHREAD_H_
#include "thread.h"
#include <string>
using namespace Shared::Platform;
using namespace std;
namespace Shared { namespace PlatformCommon {
@ -30,6 +32,7 @@ protected:
bool quit;
bool running;
string uniqueID;
virtual void setRunningStatus(bool value);
virtual void setQuitStatus(bool value);
@ -44,6 +47,9 @@ public:
virtual bool getRunningStatus();
static void shutdownAndWait(BaseThread *ppThread);
virtual void shutdownAndWait();
void setUniqueID(string value) { uniqueID = value; }
string getUniqueID() { return uniqueID; }
};
}}//end namespace

View File

@ -22,6 +22,8 @@ namespace Shared { namespace PlatformCommon {
BaseThread::BaseThread() : Thread() {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
uniqueID = "base_thread";
setQuitStatus(false);
setRunningStatus(false);
@ -29,27 +31,27 @@ BaseThread::BaseThread() : Thread() {
}
BaseThread::~BaseThread() {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
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]\n",__FILE__,__FUNCTION__,__LINE__);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] uniqueID [%s]\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str());
}
void BaseThread::signalQuit() {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] uniqueID [%s]\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str());
setQuitStatus(true);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] uniqueID [%s]\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str());
}
void BaseThread::setQuitStatus(bool value) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] uniqueID [%s]\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str());
MutexSafeWrapper safeMutex(&mutexQuit);
quit = value;
safeMutex.ReleaseLock();
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] uniqueID [%s]\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str());
}
bool BaseThread::getQuitStatus() {
@ -66,45 +68,50 @@ bool BaseThread::getQuitStatus() {
}
bool BaseThread::getRunningStatus() {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] uniqueID [%s]\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str());
bool retval = false;
MutexSafeWrapper safeMutex(&mutexRunning);
retval = running;
safeMutex.ReleaseLock();
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] running = %d\n",__FILE__,__FUNCTION__,__LINE__,retval);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] uniqueID [%s] running = %d\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str(),retval);
return retval;
}
void BaseThread::setRunningStatus(bool value) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] value = %d\n",__FILE__,__FUNCTION__,__LINE__,value);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] uniqueID [%s] value = %d\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str(),value);
MutexSafeWrapper safeMutex(&mutexRunning);
running = value;
safeMutex.ReleaseLock();
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] running = %d\n",__FILE__,__FUNCTION__,__LINE__,value);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] uniqueID [%s]\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str());
}
void BaseThread::shutdownAndWait(BaseThread *pThread) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
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]\n",__FILE__,__FUNCTION__,__LINE__);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] uniqueID [%s]\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str());
pThread->signalQuit();
sleep(0);
for( time_t elapsed = time(NULL); difftime(time(NULL),elapsed) <= 7; ) {
if(pThread->getRunningStatus() == false) {
break;
}
sleep(1);
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]\n",__FILE__,__FUNCTION__,__LINE__);
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]\n",__FILE__,__FUNCTION__,__LINE__);
//sleep(0);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] uniqueID [%s]\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str());
}
void BaseThread::shutdownAndWait() {

View File

@ -25,6 +25,11 @@ FileCRCPreCacheThread::FileCRCPreCacheThread() : BaseThread() {
void FileCRCPreCacheThread::execute() {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
if(getQuitStatus() == true) {
setRunningStatus(false);
return;
}
setRunningStatus(true);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"FILE CRC PreCache thread is running\n");
@ -82,9 +87,13 @@ SimpleTaskThread::SimpleTaskThread( SimpleTaskCallbackInterface *simpleTaskInter
void SimpleTaskThread::execute() {
try {
if(getQuitStatus() == true) {
setRunningStatus(false);
return;
}
setRunningStatus(true);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] uniqueID [%s]\n",__FILE__,__FUNCTION__,__LINE__,this->getUniqueID().c_str());
unsigned int idx = 0;
for(;this->simpleTaskInterface != NULL;) {
@ -98,12 +107,15 @@ void SimpleTaskThread::execute() {
}
if(getQuitStatus() == true) {
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] uniqueID [%s]\n",__FILE__,__FUNCTION__,__LINE__,this->getUniqueID().c_str());
break;
}
if(runTask == true) {
this->simpleTaskInterface->simpleTask();
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();
}
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] uniqueID [%s]\n",__FILE__,__FUNCTION__,__LINE__,this->getUniqueID().c_str());
}
if(this->executionCount > 0) {
@ -113,23 +125,27 @@ void SimpleTaskThread::execute() {
}
}
if(getQuitStatus() == true) {
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] uniqueID [%s]\n",__FILE__,__FUNCTION__,__LINE__,this->getUniqueID().c_str());
break;
}
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] uniqueID [%s] millisecsBetweenExecutions = %d\n",__FILE__,__FUNCTION__,__LINE__,this->getUniqueID().c_str(),millisecsBetweenExecutions);
sleep(this->millisecsBetweenExecutions);
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] uniqueID [%s] millisecsBetweenExecutions = %d\n",__FILE__,__FUNCTION__,__LINE__,this->getUniqueID().c_str(),millisecsBetweenExecutions);
}
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] uniqueID [%s]\n",__FILE__,__FUNCTION__,__LINE__,this->getUniqueID().c_str());
}
catch(const exception &ex) {
setRunningStatus(false);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] uniqueID [%s]\n",__FILE__,__FUNCTION__,__LINE__,this->getUniqueID().c_str());
throw runtime_error(ex.what());
}
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] uniqueID [%s]\n",__FILE__,__FUNCTION__,__LINE__,this->getUniqueID().c_str());
setRunningStatus(false);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] uniqueID [%s]\n",__FILE__,__FUNCTION__,__LINE__,this->getUniqueID().c_str());
}
void SimpleTaskThread::setTaskSignalled(bool value) {

View File

@ -25,7 +25,7 @@ Thread::Thread() {
Thread::~Thread() {
if(thread != NULL) {
//SDL_WaitThread(thread, NULL);
SDL_WaitThread(thread, NULL);
}
}