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:
parent
ea1c6947ab
commit
176c175206
@ -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)
|
||||
{
|
||||
|
@ -114,6 +114,7 @@ void ClientLobbyRoomProtocol::update()
|
||||
case CONNECTED:
|
||||
break;
|
||||
case DONE:
|
||||
m_state = EXITING;
|
||||
m_listener->requestTerminate(this);
|
||||
break;
|
||||
}
|
||||
|
@ -36,7 +36,8 @@ class ClientLobbyRoomProtocol : public LobbyRoomProtocol
|
||||
LINKED,
|
||||
REQUESTING_CONNECTION,
|
||||
CONNECTED,
|
||||
DONE
|
||||
DONE,
|
||||
EXITING
|
||||
};
|
||||
STATE m_state;
|
||||
};
|
||||
|
@ -103,8 +103,11 @@ void ConnectToPeer::asynchronousUpdate()
|
||||
break;
|
||||
}
|
||||
case DONE:
|
||||
m_state = EXITING;
|
||||
m_listener->requestTerminate(this);
|
||||
break;
|
||||
case EXITING:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,8 @@ class ConnectToPeer : public Protocol, public CallbackObject
|
||||
WAITING_PEER_ADDRESS,
|
||||
CONNECTING,
|
||||
CONNECTED,
|
||||
DONE
|
||||
DONE,
|
||||
EXITING
|
||||
};
|
||||
STATE m_state;
|
||||
};
|
||||
|
@ -80,6 +80,7 @@ void GetPeerAddress::asynchronousUpdate()
|
||||
}
|
||||
else if (m_state == DONE)
|
||||
{
|
||||
m_state = EXITING;
|
||||
m_listener->requestTerminate(this);
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +39,8 @@ class GetPeerAddress : public Protocol
|
||||
enum STATE
|
||||
{
|
||||
NONE,
|
||||
DONE
|
||||
DONE,
|
||||
EXITING
|
||||
};
|
||||
STATE m_state;
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
@ -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];
|
||||
|
@ -72,6 +72,7 @@ void HidePublicAddress::asynchronousUpdate()
|
||||
}
|
||||
else if (m_state == DONE)
|
||||
{
|
||||
m_state = EXITING;
|
||||
m_listener->requestTerminate(this);
|
||||
}
|
||||
}
|
||||
|
@ -38,7 +38,8 @@ class HidePublicAddress : public Protocol
|
||||
enum STATE
|
||||
{
|
||||
NONE,
|
||||
DONE
|
||||
DONE,
|
||||
EXITING
|
||||
};
|
||||
STATE m_state;
|
||||
};
|
||||
|
@ -78,6 +78,7 @@ void QuickJoinProtocol::asynchronousUpdate()
|
||||
}
|
||||
else if (m_state == DONE)
|
||||
{
|
||||
m_state = EXITING;
|
||||
m_listener->requestTerminate(this);
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,8 @@ class QuickJoinProtocol : public Protocol
|
||||
enum STATE
|
||||
{
|
||||
NONE,
|
||||
DONE
|
||||
DONE,
|
||||
EXITING
|
||||
};
|
||||
STATE m_state;
|
||||
};
|
||||
|
@ -76,8 +76,11 @@ void RequestConnection::asynchronousUpdate()
|
||||
break;
|
||||
}
|
||||
case DONE:
|
||||
m_state = EXITING;
|
||||
m_listener->requestTerminate(this);
|
||||
break;
|
||||
case EXITING:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,8 @@ class RequestConnection : public Protocol
|
||||
enum STATE
|
||||
{
|
||||
NONE,
|
||||
DONE
|
||||
DONE,
|
||||
EXITING
|
||||
};
|
||||
STATE m_state;
|
||||
|
||||
|
@ -156,8 +156,11 @@ void ServerLobbyRoomProtocol::update()
|
||||
break;
|
||||
}
|
||||
case DONE:
|
||||
m_state = EXITING;
|
||||
m_listener->requestTerminate(this);
|
||||
break;
|
||||
case EXITING:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,8 @@ class ServerLobbyRoomProtocol : public LobbyRoomProtocol
|
||||
GETTING_PUBLIC_ADDRESS,
|
||||
LAUNCHING_SERVER,
|
||||
WORKING,
|
||||
DONE
|
||||
DONE,
|
||||
EXITING
|
||||
};
|
||||
STATE m_state;
|
||||
};
|
||||
|
@ -75,6 +75,7 @@ void ShowPublicAddress::asynchronousUpdate()
|
||||
}
|
||||
else if (m_state == DONE)
|
||||
{
|
||||
m_state = EXITING;
|
||||
m_listener->requestTerminate(this);
|
||||
}
|
||||
}
|
||||
|
@ -38,7 +38,8 @@ class ShowPublicAddress : public Protocol
|
||||
enum STATE
|
||||
{
|
||||
NONE,
|
||||
DONE
|
||||
DONE,
|
||||
EXITING
|
||||
};
|
||||
STATE m_state;
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -75,6 +75,7 @@ void StartServer::asynchronousUpdate()
|
||||
}
|
||||
else if (m_state == DONE)
|
||||
{
|
||||
m_state = EXITING;
|
||||
m_listener->requestTerminate(this);
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,8 @@ class StartServer : public Protocol
|
||||
enum STATE
|
||||
{
|
||||
NONE,
|
||||
DONE
|
||||
DONE,
|
||||
EXITING
|
||||
};
|
||||
STATE m_state;
|
||||
};
|
||||
|
@ -74,6 +74,7 @@ void StopServer::asynchronousUpdate()
|
||||
}
|
||||
else if (m_state == DONE)
|
||||
{
|
||||
m_state = EXITING;
|
||||
m_listener->requestTerminate(this);
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,8 @@ class StopServer : public Protocol
|
||||
enum STATE
|
||||
{
|
||||
NONE,
|
||||
DONE
|
||||
DONE,
|
||||
EXITING
|
||||
};
|
||||
STATE m_state;
|
||||
};
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user