Fix race condition when user installs addons live in lobby

This commit is contained in:
Benau 2019-11-30 13:10:33 +08:00
parent b2d496798f
commit e450968bef
4 changed files with 32 additions and 29 deletions

View File

@ -45,7 +45,6 @@ LobbyProtocol::LobbyProtocol()
resetGameStartedProgress();
m_game_setup = new GameSetup();
m_end_voting_period.store(0);
m_current_track.store(-1);
} // LobbyProtocol
// ----------------------------------------------------------------------------
@ -149,7 +148,9 @@ void LobbyProtocol::configRemoteKart(
*/
void LobbyProtocol::setup()
{
m_current_track.store(-1);
std::unique_lock<std::mutex> ul(m_current_track_mutex);
m_current_track.clear();
ul.unlock();
m_last_live_join_util_ticks = 0;
resetVotingTime();
m_peers_votes.clear();
@ -236,8 +237,8 @@ bool LobbyProtocol::hasLiveJoiningRecently() const
//-----------------------------------------------------------------------------
Track* LobbyProtocol::getPlayingTrack() const
{
int cur_idx = m_current_track.load();
if (cur_idx != -1)
return track_manager->getTrack(cur_idx);
return NULL;
std::unique_lock<std::mutex> ul(m_current_track_mutex);
std::string track_ident = m_current_track;
ul.unlock();
return track_manager->getTrack(track_ident);
} // getPlayingTrack

View File

@ -31,6 +31,7 @@ class Track;
#include <cassert>
#include <map>
#include <memory>
#include <mutex>
#include <thread>
#include <vector>
@ -125,8 +126,11 @@ protected:
* transformation in server, and reset smooth network body in client. */
int m_last_live_join_util_ticks;
/** Store current playing track in id. */
std::atomic<int> m_current_track;
/** Mutex to protect m_current_track. */
mutable std::mutex m_current_track_mutex;
/** Store current playing track in name. */
std::string m_current_track;
/** Stores data about the online game to play. */
GameSetup* m_game_setup;
@ -222,7 +226,17 @@ public:
// ------------------------------------------------------------------------
bool hasLiveJoiningRecently() const;
// ------------------------------------------------------------------------
void storePlayingTrack(int track_id) { m_current_track.store(track_id); }
void storePlayingTrack(const std::string& track_ident)
{
std::lock_guard<std::mutex> lock(m_current_track_mutex);
m_current_track = track_ident;
}
// ------------------------------------------------------------------------
std::string getPlayingTrackIdent() const
{
std::lock_guard<std::mutex> lock(m_current_track_mutex);
return m_current_track;
}
// ------------------------------------------------------------------------
Track* getPlayingTrack() const;
}; // class LobbyProtocol

View File

@ -1868,11 +1868,10 @@ void ServerLobby::update(int ticks)
if (w && w->getPhase() == World::RACE_PHASE)
{
storePlayingTrack(track_manager->getTrackIndexByIdent(
race_manager->getTrackName()));
storePlayingTrack(race_manager->getTrackName());
}
else
storePlayingTrack(-1);
storePlayingTrack("");
// Reset server to initial state if no more connected players
if (m_rs_state.load() == RS_WAITING)
@ -2481,9 +2480,9 @@ void ServerLobby::checkIncomingConnectionRequests()
request->addParameter("current-players", getLobbyPlayers());
request->addParameter("game-started",
m_state.load() == WAITING_FOR_START_GAME ? 0 : 1);
Track* current_track = getPlayingTrack();
if (current_track)
request->addParameter("current-track", current_track->getIdent());
std::string current_track = getPlayingTrackIdent();
if (!current_track.empty())
request->addParameter("current-track", getPlayingTrackIdent());
request->queue();
} // checkIncomingConnectionRequests

View File

@ -34,8 +34,6 @@
#include "network/server_config.hpp"
#include "network/stk_ipv6.hpp"
#include "network/stk_peer.hpp"
#include "tracks/track.hpp"
#include "tracks/track_manager.hpp"
#include "utils/log.hpp"
#include "utils/separate_process.hpp"
#include "utils/string_utils.hpp"
@ -1026,11 +1024,7 @@ void STKHost::mainLoop()
auto progress = sl->getGameStartedProgress();
ping_packet.addUInt32(progress.first)
.addUInt32(progress.second);
std::string current_track;
Track* t = sl->getPlayingTrack();
if (t)
current_track = t->getIdent();
ping_packet.encodeString(current_track);
ping_packet.encodeString(sl->getPlayingTrackIdent());
}
else
{
@ -1245,9 +1239,7 @@ void STKHost::mainLoop()
{
lp->setGameStartedProgress(
std::make_pair(remaining_time, progress));
int idx = track_manager
->getTrackIndexByIdent(current_track);
lp->storePlayingTrack(idx);
lp->storePlayingTrack(current_track);
}
}
}
@ -1340,10 +1332,7 @@ void STKHost::handleDirectSocketRequest(Network* direct_socket,
s.addUInt8((uint8_t)
(sl->getCurrentState() == ServerLobby::WAITING_FOR_START_GAME ?
0 : 1));
std::string current_track;
if (Track* t = sl->getPlayingTrack())
current_track = t->getIdent();
s.encodeString(current_track);
s.encodeString(sl->getPlayingTrackIdent());
direct_socket->sendRawPacket(s, sender);
} // if message is server-requested
else if (command == connection_cmd)