Add a thread safe way to clear game protocols when deleting world

This commit is contained in:
Benau 2019-01-05 14:20:30 +08:00
parent 37e5ea6806
commit 641b16e1c7
3 changed files with 26 additions and 5 deletions

View File

@ -960,6 +960,19 @@ void ClientLobby::backToLobby(Event *event)
setup();
m_auto_started = false;
m_state.store(CONNECTED);
RaceEventManager::getInstance()->stop();
auto gep = RaceEventManager::getInstance()->getProtocol();
if (gep)
gep->requestTerminate();
auto gp = GameProtocol::lock();
if (gp)
{
auto lock = gp->acquireWorldDeletingMutex();
gp->requestTerminate();
RaceResultGUI::getInstance()->backToLobby();
}
else
RaceResultGUI::getInstance()->backToLobby();
NetworkString &data = event->data();

View File

@ -115,6 +115,11 @@ bool GameProtocol::notifyEventAsynchronous(Event* event)
{
if(!checkDataSize(event, 1)) return true;
// Ignore events arriving when client has already exited
auto lock = acquireWorldDeletingMutex();
if (!World::getWorld())
return true;
NetworkString &data = event->data();
uint8_t message_type = data.getUInt8();
switch (message_type)
@ -398,10 +403,6 @@ void GameProtocol::sendState()
*/
void GameProtocol::handleState(Event *event)
{
// Ignore events arriving when client has already exited
if (!World::getWorld())
return;
assert(NetworkConfig::get()->isClient());
NetworkString &data = event->data();
int ticks = data.getUInt32();

View File

@ -28,6 +28,7 @@
#include <cstdlib>
#include <map>
#include <mutex>
#include <vector>
#include <tuple>
@ -39,6 +40,9 @@ class GameProtocol : public Protocol
, public EventRewinder
{
private:
/* Used to check if deleting world is doing at the same the for
* asynchronous event update. */
mutable std::mutex m_world_deleting_mutex;
/** The type of game events to be forwarded to the server. */
enum { GP_CONTROLLER_ACTION,
@ -138,6 +142,9 @@ public:
NetworkString* getState() const { return m_data_to_send; }
// ------------------------------------------------------------------------
void addInitialTicks(STKPeer* p, int ticks);
// ------------------------------------------------------------------------
std::unique_lock<std::mutex> acquireWorldDeletingMutex() const
{ return std::unique_lock<std::mutex>(m_world_deleting_mutex); }
}; // class GameProtocol