dually enhanced thread protocols management to avoid protocols asking their own deletion multiple times (which of course causes a segfault)

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/hilnius@13268 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hilnius 2013-07-18 15:58:46 +00:00
parent ea1c6947ab
commit 176c175206
27 changed files with 60 additions and 15 deletions

View File

@ -202,6 +202,15 @@ void ProtocolManager::requestTerminate(Protocol* protocol)
req.type = PROTOCOL_REQUEST_TERMINATE;
// add it to the request stack
pthread_mutex_lock(&m_requests_mutex);
// check that the request does not already exist :
for (unsigned int i = 0; i < m_requests.size(); i++)
{
if (m_requests[i].protocol_info.protocol == protocol)
{
pthread_mutex_unlock(&m_requests_mutex);
return;
}
}
m_requests.push_back(req);
pthread_mutex_unlock(&m_requests_mutex);
}
@ -213,11 +222,11 @@ void ProtocolManager::startProtocol(ProtocolInfo protocol)
pthread_mutex_lock(&m_asynchronous_protocols_mutex);
Log::info("ProtocolManager", "A %s protocol with id=%u has been started. There are %ld protocols running.", typeid(*protocol.protocol).name(), protocol.id, m_protocols.size()+1);
m_protocols.push_back(protocol);
pthread_mutex_unlock(&m_protocols_mutex);
pthread_mutex_unlock(&m_asynchronous_protocols_mutex);
// setup the protocol and notify it that it's started
protocol.protocol->setListener(this);
protocol.protocol->setup();
pthread_mutex_unlock(&m_protocols_mutex);
pthread_mutex_unlock(&m_asynchronous_protocols_mutex);
}
void ProtocolManager::stopProtocol(ProtocolInfo protocol)
{

View File

@ -114,6 +114,7 @@ void ClientLobbyRoomProtocol::update()
case CONNECTED:
break;
case DONE:
m_state = EXITING;
m_listener->requestTerminate(this);
break;
}

View File

@ -36,7 +36,8 @@ class ClientLobbyRoomProtocol : public LobbyRoomProtocol
LINKED,
REQUESTING_CONNECTION,
CONNECTED,
DONE
DONE,
EXITING
};
STATE m_state;
};

View File

@ -103,8 +103,11 @@ void ConnectToPeer::asynchronousUpdate()
break;
}
case DONE:
m_state = EXITING;
m_listener->requestTerminate(this);
break;
case EXITING:
break;
}
}

View File

@ -46,7 +46,8 @@ class ConnectToPeer : public Protocol, public CallbackObject
WAITING_PEER_ADDRESS,
CONNECTING,
CONNECTED,
DONE
DONE,
EXITING
};
STATE m_state;
};

View File

@ -80,6 +80,7 @@ void GetPeerAddress::asynchronousUpdate()
}
else if (m_state == DONE)
{
m_state = EXITING;
m_listener->requestTerminate(this);
}
}

View File

@ -39,7 +39,8 @@ class GetPeerAddress : public Protocol
enum STATE
{
NONE,
DONE
DONE,
EXITING
};
STATE m_state;

View File

@ -200,7 +200,11 @@ void GetPublicAddress::asynchronousUpdate()
}
if (m_state == ADDRESS_KNOWN)
{
m_state = EXITING;
// terminate the protocol
m_listener->requestTerminate(this);
}
if (m_state == EXITING)
{
}
}

View File

@ -38,7 +38,8 @@ class GetPublicAddress : public Protocol
{
NOTHING_DONE,
TEST_SENT,
ADDRESS_KNOWN
ADDRESS_KNOWN,
EXITING
};
STATE m_state;
uint32_t m_stun_tansaction_id[3];

View File

@ -72,6 +72,7 @@ void HidePublicAddress::asynchronousUpdate()
}
else if (m_state == DONE)
{
m_state = EXITING;
m_listener->requestTerminate(this);
}
}

View File

@ -38,7 +38,8 @@ class HidePublicAddress : public Protocol
enum STATE
{
NONE,
DONE
DONE,
EXITING
};
STATE m_state;
};

View File

@ -78,6 +78,7 @@ void QuickJoinProtocol::asynchronousUpdate()
}
else if (m_state == DONE)
{
m_state = EXITING;
m_listener->requestTerminate(this);
}
}

View File

@ -20,7 +20,8 @@ class QuickJoinProtocol : public Protocol
enum STATE
{
NONE,
DONE
DONE,
EXITING
};
STATE m_state;
};

View File

@ -76,8 +76,11 @@ void RequestConnection::asynchronousUpdate()
break;
}
case DONE:
m_state = EXITING;
m_listener->requestTerminate(this);
break;
case EXITING:
break;
}
}

View File

@ -20,7 +20,8 @@ class RequestConnection : public Protocol
enum STATE
{
NONE,
DONE
DONE,
EXITING
};
STATE m_state;

View File

@ -156,8 +156,11 @@ void ServerLobbyRoomProtocol::update()
break;
}
case DONE:
m_state = EXITING;
m_listener->requestTerminate(this);
break;
case EXITING:
break;
}
}

View File

@ -33,7 +33,8 @@ class ServerLobbyRoomProtocol : public LobbyRoomProtocol
GETTING_PUBLIC_ADDRESS,
LAUNCHING_SERVER,
WORKING,
DONE
DONE,
EXITING
};
STATE m_state;
};

View File

@ -75,6 +75,7 @@ void ShowPublicAddress::asynchronousUpdate()
}
else if (m_state == DONE)
{
m_state = EXITING;
m_listener->requestTerminate(this);
}
}

View File

@ -38,7 +38,8 @@ class ShowPublicAddress : public Protocol
enum STATE
{
NONE,
DONE
DONE,
EXITING
};
STATE m_state;
};

View File

@ -174,6 +174,7 @@ void StartGameProtocol::update()
}
else if (m_state == READY)
{
m_state = EXITING;
m_listener->requestTerminate(this);
}
}
@ -188,6 +189,7 @@ void StartGameProtocol::ready() // on clients, means the loading is finished
Log::info("StartGameProtocol", "Player ready, notifying server.");
m_listener->sendMessage(this, ns, true);
m_state = READY;
m_ready = true;
return;
}
else // on the server

View File

@ -10,7 +10,7 @@ class NetworkPlayerProfile;
class StartGameProtocol : public Protocol
{
protected:
enum STATE { NONE, SYNCHRONIZATION_WAIT, LOADING, READY };
enum STATE { NONE, SYNCHRONIZATION_WAIT, LOADING, READY, EXITING };
std::map<NetworkPlayerProfile*, STATE> m_player_states;
GameSetup* m_game_setup;

View File

@ -75,6 +75,7 @@ void StartServer::asynchronousUpdate()
}
else if (m_state == DONE)
{
m_state = EXITING;
m_listener->requestTerminate(this);
}
}

View File

@ -22,7 +22,8 @@ class StartServer : public Protocol
enum STATE
{
NONE,
DONE
DONE,
EXITING
};
STATE m_state;
};

View File

@ -74,6 +74,7 @@ void StopServer::asynchronousUpdate()
}
else if (m_state == DONE)
{
m_state = EXITING;
m_listener->requestTerminate(this);
}
}

View File

@ -22,7 +22,8 @@ class StopServer : public Protocol
enum STATE
{
NONE,
DONE
DONE,
EXITING
};
STATE m_state;
};

View File

@ -110,6 +110,7 @@ void SynchronizationProtocol::setup()
{
Log::info("SynchronizationProtocol", "Ready !");
m_countdown = 5.0; // init the countdown to 5s
m_has_quit = false;
}
//-----------------------------------------------------------------------------
@ -123,8 +124,9 @@ void SynchronizationProtocol::asynchronousUpdate()
m_countdown -= (current_time - m_last_countdown_update);
m_last_countdown_update = current_time;
Log::debug("SynchronizationProtocol", "Update! Countdown remaining : %f", m_countdown);
if (m_countdown < 0.0)
if (m_countdown < 0.0 && !m_has_quit)
{
m_has_quit = true;
Log::info("SynchronizationProtocol", "Countdown finished. Starting now.");
m_listener->requestStart(new KartUpdateProtocol());
m_listener->requestTerminate(this);

View File

@ -29,6 +29,7 @@ class SynchronizationProtocol : public Protocol
bool m_countdown_activated;
double m_countdown;
double m_last_countdown_update;
bool m_has_quit;
};
#endif // SYNCHRONIZATION_PROTOCOL_HPP