fix a blocking infinite while

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/hilnius@13243 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hilnius 2013-07-15 13:44:17 +00:00
parent e95bafca44
commit 13aa1d52c8
8 changed files with 60 additions and 56 deletions

View File

@ -1,5 +1,7 @@
#include "network/network_world.hpp"
#include "network/protocol_manager.hpp"
#include "network/protocols/synchronization_protocol.hpp"
#include "modes/world.hpp"
NetworkWorld::NetworkWorld()
@ -13,5 +15,14 @@ NetworkWorld::~NetworkWorld()
void NetworkWorld::update(float dt)
{
SynchronizationProtocol* protocol = static_cast<SynchronizationProtocol*>(
ProtocolManager::getInstance()->getProtocol(PROTOCOL_SYNCHRONIZATION));
if (protocol) // if this protocol exists, that's that we play online
{
if (protocol->getCountdown() > 0)
{
return;
}
}
World::getWorld()->updateWorld(dt);
}

View File

@ -87,9 +87,19 @@ ProtocolManager::~ProtocolManager()
void ProtocolManager::notifyEvent(Event* event)
{
Event* event2 = new Event(*event);
pthread_mutex_lock(&m_events_mutex);
m_events_to_process.push_back(event2); // add the event to the queue
pthread_mutex_unlock(&m_events_mutex);
int result = pthread_mutex_trylock(&m_protocols_mutex);
if (result == 0) // locked successfully
{
// if we can propagate the event now, do so:
propagateEvent(event2);
pthread_mutex_unlock(&m_protocols_mutex);
}
else
{
pthread_mutex_lock(&m_events_mutex);
m_events_to_process.push_back(event2); // add the event to the queue
pthread_mutex_unlock(&m_events_mutex);
}
}
void ProtocolManager::sendMessage(Protocol* sender, const NetworkString& message, bool reliable)
@ -236,6 +246,33 @@ void ProtocolManager::protocolTerminated(ProtocolInfo protocol)
pthread_mutex_unlock(&m_protocols_mutex);
}
void ProtocolManager::propagateEvent(Event* event)
{
PROTOCOL_TYPE searchedProtocol = PROTOCOL_NONE;
if (event->type == EVENT_TYPE_MESSAGE)
{
if (event->data.size() > 0)
searchedProtocol = (PROTOCOL_TYPE)(event->data.getAndRemoveUInt8());
}
if (event->type == EVENT_TYPE_CONNECTED)
{
searchedProtocol = PROTOCOL_CONNECTION;
}
for (unsigned int i = 0; i < m_protocols.size() ; i++)
{
if (m_protocols[i].protocol->getProtocolType() == searchedProtocol || event->type == EVENT_TYPE_DISCONNECTED) // pass data to protocols even when paused
m_protocols[i].protocol->notifyEvent(event);
}
if (searchedProtocol == PROTOCOL_NONE) // no protocol was aimed, show the msg to debug
{
Log::debug("ProtocolManager", "Message is \"%s\"", event->data.c_str());
}
// because we made a copy of the event
delete event->peer; // no more need of that
delete event;
}
void ProtocolManager::update()
{
// before updating, notice protocols that they have received information
@ -247,29 +284,7 @@ void ProtocolManager::update()
m_events_to_process.pop_back();
pthread_mutex_unlock(&m_events_mutex); // release the mutex
PROTOCOL_TYPE searchedProtocol = PROTOCOL_NONE;
if (event->type == EVENT_TYPE_MESSAGE)
{
if (event->data.size() > 0)
searchedProtocol = (PROTOCOL_TYPE)(event->data.getAndRemoveUInt8());
}
if (event->type == EVENT_TYPE_CONNECTED)
{
searchedProtocol = PROTOCOL_CONNECTION;
}
for (unsigned int i = 0; i < m_protocols.size() ; i++)
{
if (m_protocols[i].protocol->getProtocolType() == searchedProtocol || event->type == EVENT_TYPE_DISCONNECTED) // pass data to protocols even when paused
m_protocols[i].protocol->notifyEvent(event);
}
if (searchedProtocol == PROTOCOL_NONE) // no protocol was aimed, show the msg to debug
{
Log::debug("ProtocolManager", "Message is \"%s\"", event->data.c_str());
}
// because we made a copy of the event
delete event->peer; // no more need of that
delete event;
propagateEvent(event);
}
// now update all protocols

View File

@ -258,6 +258,8 @@ class ProtocolManager : public Singleton<ProtocolManager>
*/
virtual void protocolTerminated(ProtocolInfo protocol);
void propagateEvent(Event* event);
// protected members
/*!
* \brief Contains the running protocols.

View File

@ -25,7 +25,6 @@ StartGameProtocol::StartGameProtocol(GameSetup* game_setup) :
m_player_states.insert(std::pair<NetworkPlayerProfile*, STATE>(players[i], LOADING));
}
m_ready_count = 0;
m_ready = NULL;
}
StartGameProtocol::~StartGameProtocol()
@ -58,7 +57,7 @@ void StartGameProtocol::notifyEvent(Event* event)
SynchronizationProtocol* protocol = static_cast<SynchronizationProtocol*>(m_listener->getProtocol(PROTOCOL_SYNCHRONIZATION));
if (protocol)
{
protocol->startCountdown(m_ready, 5000); // 5 seconds countdown
protocol->startCountdown(5000); // 5 seconds countdown
Log::info("StartGameProtocol", "All players ready, starting countdown.");
m_state = READY;
}
@ -77,7 +76,6 @@ void StartGameProtocol::setup()
{
m_state = NONE;
m_ready_count = 0;
m_ready = NULL;
Log::info("SynchronizationProtocol", "Ready !");
}
@ -135,7 +133,6 @@ void StartGameProtocol::update()
}
else if (m_state == READY)
{
*m_ready = true;
m_listener->requestTerminate(this);
}
}
@ -155,7 +152,3 @@ void StartGameProtocol::ready() // on clients, means the loading is finished
}
}
void StartGameProtocol::onReadyChange(bool* start)
{
m_ready = start;
}

View File

@ -14,7 +14,6 @@ class StartGameProtocol : public Protocol
std::map<NetworkPlayerProfile*, STATE> m_player_states;
GameSetup* m_game_setup;
bool* m_ready; //!< Set to true when the game can start
int m_ready_count;
double m_sending_time;
@ -29,7 +28,6 @@ class StartGameProtocol : public Protocol
virtual void update();
void ready();
void onReadyChange(bool* start);
};

View File

@ -17,7 +17,6 @@ SynchronizationProtocol::SynchronizationProtocol() : Protocol(NULL, PROTOCOL_SYN
m_successed_pings.resize(size);
m_total_diff.resize(size);
m_average_ping.resize(size);
m_ready = NULL;
m_countdown_activated = false;
}
@ -132,9 +131,8 @@ void SynchronizationProtocol::update()
//-----------------------------------------------------------------------------
void SynchronizationProtocol::startCountdown(bool* ready, uint32_t ms_countdown)
void SynchronizationProtocol::startCountdown(int ms_countdown)
{
m_ready = ready;
m_countdown_activated = true;
m_countdown = ms_countdown;
m_last_countdown_update = Time::getRealTime();

View File

@ -15,7 +15,9 @@ class SynchronizationProtocol : public Protocol
virtual void setup();
virtual void update();
void startCountdown(bool* ready, uint32_t ms_countdown);
void startCountdown(int ms_countdown);
int getCountdown() { return m_countdown; }
protected:
std::vector<std::map<uint32_t, double> > m_pings;
@ -23,9 +25,8 @@ class SynchronizationProtocol : public Protocol
std::vector<uint32_t> m_pings_count;
std::vector<uint32_t> m_successed_pings;
std::vector<double> m_total_diff;
bool* m_ready;
bool m_countdown_activated;
uint32_t m_countdown;
int m_countdown;
double m_last_countdown_update;
};

View File

@ -461,20 +461,6 @@ void RaceManager::startNextRace()
m_kart_status[i].m_last_score = m_kart_status[i].m_score;
m_kart_status[i].m_last_time = 0;
}
StartGameProtocol* protocol = static_cast<StartGameProtocol*>(
ProtocolManager::getInstance()->getProtocol(PROTOCOL_START_GAME));
if (protocol) // if this protocol exists, that's that we play online
{
Log::info("RaceManager", "Game ready, waiting server synchronization.");
bool ready = false;
protocol->ready();
protocol->onReadyChange(&ready);
while(!ready) // wait the protocol to say we can start
{
}
}
} // startNextRace
//-----------------------------------------------------------------------------