From 95ca3fcac1efb9a9d74f4d12ee262e43b7ffcb33 Mon Sep 17 00:00:00 2001 From: hiker Date: Wed, 14 Dec 2016 17:23:22 +1100 Subject: [PATCH] Try to fix rare GUI crash, likely caused by pushing a screen in the network thread while the gui is being drawn. Made the messages causing this synchronous, i.e. executed by the main thread. --- src/network/protocols/client_lobby.cpp | 2 +- src/network/protocols/server_lobby.cpp | 28 +++++++++++++++++++++++-- src/network/protocols/server_lobby.hpp | 1 + src/states_screens/networking_lobby.cpp | 1 + 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/network/protocols/client_lobby.cpp b/src/network/protocols/client_lobby.cpp index 8941a449b..16ffc9ab5 100644 --- a/src/network/protocols/client_lobby.cpp +++ b/src/network/protocols/client_lobby.cpp @@ -237,6 +237,7 @@ bool ClientLobby::notifyEvent(Event* event) message_type); switch(message_type) { + case LE_START_SELECTION: startSelection(event); break; case LE_KART_SELECTION_UPDATE: kartSelectionUpdate(event); break; case LE_LOAD_WORLD: loadWorld(); break; case LE_RACE_FINISHED: raceFinished(event); break; @@ -266,7 +267,6 @@ bool ClientLobby::notifyEventAsynchronous(Event* event) case LE_NEW_PLAYER_CONNECTED: newPlayer(event); break; case LE_PLAYER_DISCONNECTED : disconnectedPlayer(event); break; case LE_START_RACE: startGame(event); break; - case LE_START_SELECTION: startSelection(event); break; case LE_CONNECTION_REFUSED: connectionRefused(event); break; case LE_CONNECTION_ACCEPTED: connectionAccepted(event); break; case LE_KART_SELECTION_REFUSED: kartSelectionRefused(event); break; diff --git a/src/network/protocols/server_lobby.cpp b/src/network/protocols/server_lobby.cpp index 144ba5e5b..bfc7bbd76 100644 --- a/src/network/protocols/server_lobby.cpp +++ b/src/network/protocols/server_lobby.cpp @@ -122,6 +122,29 @@ void ServerLobby::setup() } // setup +//----------------------------------------------------------------------------- +bool ServerLobby::notifyEvent(Event* event) +{ + assert(m_game_setup); // assert that the setup exists + if (event->getType() != EVENT_TYPE_MESSAGE) + return false; + + NetworkString &data = event->data(); + assert(data.size()); // message not empty + uint8_t message_type; + message_type = data.getUInt8(); + Log::info("ServerLobby", "Synchronous message received with type %d.", + message_type); + switch (message_type) + { + case LE_REQUEST_BEGIN: startSelection(event); break; + default: Log::error("ServerLobby", "Unknown message type %d - ignored.", + message_type); + break; + } // switch message_type + return true; +} // notifyEvent + //----------------------------------------------------------------------------- bool ServerLobby::notifyEventAsynchronous(Event* event) @@ -138,7 +161,6 @@ bool ServerLobby::notifyEventAsynchronous(Event* event) switch(message_type) { case LE_CONNECTION_REQUESTED: connectionRequested(event); break; - case LE_REQUEST_BEGIN: startSelection(event); break; case LE_KART_SELECTION: kartSelectionRequested(event); break; case LE_CLIENT_LOADED_WORLD: finishedLoadingWorldClient(event); break; case LE_STARTED_RACE: startedRaceOnClient(event); break; @@ -357,7 +379,9 @@ void ServerLobby::startSelection(const Event *event) } const std::vector &peers = STKHost::get()->getPeers(); NetworkString *ns = getNetworkString(1); - // start selection + // Start selection - must be synchronous since the receiver pushes + // a new screen, which must be donefrom the main thread. + ns->setSynchronous(true); ns->addUInt8(LE_START_SELECTION); sendMessageToPeersChangingToken(ns, /*reliable*/true); delete ns; diff --git a/src/network/protocols/server_lobby.hpp b/src/network/protocols/server_lobby.hpp index d358a545f..0121cc1dd 100644 --- a/src/network/protocols/server_lobby.hpp +++ b/src/network/protocols/server_lobby.hpp @@ -76,6 +76,7 @@ public: virtual ~ServerLobby(); virtual bool notifyEventAsynchronous(Event* event) OVERRIDE; + virtual bool notifyEvent(Event* event) OVERRIDE; virtual void setup() OVERRIDE; virtual void update(float dt) OVERRIDE; virtual void asynchronousUpdate() OVERRIDE {}; diff --git a/src/states_screens/networking_lobby.cpp b/src/states_screens/networking_lobby.cpp index 736c47dea..2a3a68b84 100644 --- a/src/states_screens/networking_lobby.cpp +++ b/src/states_screens/networking_lobby.cpp @@ -170,6 +170,7 @@ void NetworkingLobby::eventCallback(Widget* widget, const std::string& name, { // Send a message to the server to start NetworkString start(PROTOCOL_LOBBY_ROOM); + start.setSynchronous(true); start.addUInt8(LobbyProtocol::LE_REQUEST_BEGIN); STKHost::get()->sendToServer(&start, true); }