Canceling asio timers has bad semantics, and causes loads of trouble. Therefore, cancelled timers are simply marked as such, and the asio callback is silently ignored. This fixes several crashes, if players were removed from a game due to an error, because some timers were not cancelled. *sigh* This one took a lot of nerve.
This commit is contained in:
@@ -48,7 +48,7 @@ class SendDataManager : public boost::enable_shared_from_this<SendDataManager>
|
||||
{
|
||||
}
|
||||
|
||||
void HandleWrite(const boost::system::error_code& error);
|
||||
void HandleWrite(const boost::system::error_code &error);
|
||||
|
||||
void AsyncSendNextPacket(bool handlerMode = false);
|
||||
|
||||
@@ -61,7 +61,7 @@ class SendDataManager : public boost::enable_shared_from_this<SendDataManager>
|
||||
|
||||
|
||||
void
|
||||
SendDataManager::HandleWrite(const boost::system::error_code& error)
|
||||
SendDataManager::HandleWrite(const boost::system::error_code &error)
|
||||
{
|
||||
// TODO error handling
|
||||
AsyncSendNextPacket(true);
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include <core/loghelper.h>
|
||||
|
||||
|
||||
#define NET_SERVER_LISTEN_BACKLOG 5
|
||||
#define NET_SERVER_LISTEN_BACKLOG 20
|
||||
|
||||
using namespace std;
|
||||
using boost::asio::ip::tcp;
|
||||
@@ -96,7 +96,7 @@ ServerAcceptHelper::InternalListen(unsigned serverPort, bool ipv6, bool sctp)
|
||||
|
||||
void
|
||||
ServerAcceptHelper::HandleAccept(boost::shared_ptr<boost::asio::ip::tcp::socket> acceptedSocket,
|
||||
const boost::system::error_code& error)
|
||||
const boost::system::error_code &error)
|
||||
{
|
||||
if (!error)
|
||||
{
|
||||
|
||||
@@ -46,7 +46,16 @@ ServerGame::ServerGame(ServerLobbyThread &lobbyThread, u_int32_t id, const strin
|
||||
LOG_VERBOSE("Game object " << GetId() << " created.");
|
||||
|
||||
m_receiver.reset(new ReceiverHelper);
|
||||
}
|
||||
|
||||
ServerGame::~ServerGame()
|
||||
{
|
||||
LOG_VERBOSE("Game object " << GetId() << " destructed.");
|
||||
}
|
||||
|
||||
void
|
||||
ServerGame::Init()
|
||||
{
|
||||
m_voteKickTimerId = GetLobbyThread().GetTimerManager().RegisterTimer(
|
||||
SERVER_CHECK_VOTE_KICK_INTERVAL_MSEC,
|
||||
boost::bind(&ServerGame::TimerVoteKick, this),
|
||||
@@ -55,12 +64,11 @@ ServerGame::ServerGame(ServerLobbyThread &lobbyThread, u_int32_t id, const strin
|
||||
SetState(SERVER_INITIAL_STATE::Instance());
|
||||
}
|
||||
|
||||
ServerGame::~ServerGame()
|
||||
void
|
||||
ServerGame::Exit()
|
||||
{
|
||||
GetLobbyThread().GetTimerManager().UnregisterTimer(m_voteKickTimerId);
|
||||
GetLobbyThread().GetTimerManager().UnregisterTimer(m_stateTimerId);
|
||||
|
||||
LOG_VERBOSE("Game object " << GetId() << " destructed.");
|
||||
}
|
||||
|
||||
u_int32_t
|
||||
|
||||
@@ -400,7 +400,7 @@ ServerGameStateInit::TimerAdminWarning(ServerGame &server)
|
||||
server.GetLobbyThread().GetSender().Send(session.sessionData, warning);
|
||||
}
|
||||
// Start timeout timer.
|
||||
server.GetLobbyThread().GetTimerManager().RestartTimer(
|
||||
server.GetLobbyThread().GetTimerManager().AddTimer(
|
||||
server.GetStateTimerId(),
|
||||
SERVER_GAME_ADMIN_WARNING_REMAINING_SEC * 1000,
|
||||
boost::bind(&ServerGameStateInit::TimerAdminTimeout, this, boost::ref(server)));
|
||||
@@ -701,7 +701,7 @@ ServerGameStateHand::TimerLoop(ServerGame &server)
|
||||
server.SendToAllPlayers(allIn, SessionData::Game);
|
||||
curGame.getCurrentHand()->setCardsShown(true);
|
||||
|
||||
server.GetLobbyThread().GetTimerManager().RestartTimer(
|
||||
server.GetLobbyThread().GetTimerManager().AddTimer(
|
||||
server.GetStateTimerId(),
|
||||
SERVER_SHOW_CARDS_DELAY_SEC * 1000,
|
||||
boost::bind(&ServerGameStateHand::TimerLoop, this, boost::ref(server)));
|
||||
@@ -710,7 +710,7 @@ ServerGameStateHand::TimerLoop(ServerGame &server)
|
||||
{
|
||||
SendNewRoundCards(server, curGame, newRound);
|
||||
|
||||
server.GetLobbyThread().GetTimerManager().RestartTimer(
|
||||
server.GetLobbyThread().GetTimerManager().AddTimer(
|
||||
server.GetStateTimerId(),
|
||||
GetDealCardsDelaySec(server) * 1000,
|
||||
boost::bind(&ServerGameStateHand::TimerLoop, this, boost::ref(server)));
|
||||
@@ -741,7 +741,7 @@ ServerGameStateHand::TimerLoop(ServerGame &server)
|
||||
// If the player is computer controlled, let the engine act.
|
||||
if (curPlayer->getMyType() == PLAYER_TYPE_COMPUTER)
|
||||
{
|
||||
server.GetLobbyThread().GetTimerManager().RestartTimer(
|
||||
server.GetLobbyThread().GetTimerManager().AddTimer(
|
||||
server.GetStateTimerId(),
|
||||
SERVER_COMPUTER_ACTION_DELAY_SEC * 1000,
|
||||
boost::bind(&ServerGameStateHand::TimerComputerAction, this, boost::ref(server)));
|
||||
@@ -750,7 +750,7 @@ ServerGameStateHand::TimerLoop(ServerGame &server)
|
||||
else if (!server.GetSessionManager().IsPlayerConnected(curPlayer->getMyName()))
|
||||
{
|
||||
PerformPlayerAction(server, curPlayer, PLAYER_ACTION_FOLD, 0);
|
||||
server.GetLobbyThread().GetTimerManager().RestartTimer(
|
||||
server.GetLobbyThread().GetTimerManager().AddTimer(
|
||||
server.GetStateTimerId(),
|
||||
SERVER_LOOP_DELAY_MSEC,
|
||||
boost::bind(&ServerGameStateHand::TimerLoop, this, boost::ref(server)));
|
||||
@@ -833,14 +833,14 @@ ServerGameStateHand::TimerLoop(ServerGame &server)
|
||||
else if (playersWithCash.size() == 1)
|
||||
{
|
||||
// View a dialog for a new game - delayed.
|
||||
server.GetLobbyThread().GetTimerManager().RestartTimer(
|
||||
server.GetLobbyThread().GetTimerManager().AddTimer(
|
||||
server.GetStateTimerId(),
|
||||
SERVER_DELAY_NEXT_GAME_SEC * 1000,
|
||||
boost::bind(&ServerGameStateHand::TimerNextGame, this, boost::ref(server)));
|
||||
}
|
||||
else
|
||||
{
|
||||
server.GetLobbyThread().GetTimerManager().RestartTimer(
|
||||
server.GetLobbyThread().GetTimerManager().AddTimer(
|
||||
server.GetStateTimerId(),
|
||||
SERVER_DELAY_NEXT_HAND_SEC * 1000,
|
||||
boost::bind(&ServerGameStateHand::TimerNextHand, this, boost::ref(server)));
|
||||
@@ -855,7 +855,7 @@ ServerGameStateHand::TimerShowCards(ServerGame &server)
|
||||
Game &curGame = server.GetGame();
|
||||
SendNewRoundCards(server, curGame, curGame.getCurrentHand()->getCurrentRound());
|
||||
|
||||
server.GetLobbyThread().GetTimerManager().RestartTimer(
|
||||
server.GetLobbyThread().GetTimerManager().AddTimer(
|
||||
server.GetStateTimerId(),
|
||||
GetDealCardsDelaySec(server) * 1000,
|
||||
boost::bind(&ServerGameStateHand::TimerLoop, this, boost::ref(server)));
|
||||
|
||||
@@ -563,7 +563,7 @@ ServerLobbyThread::RegisterTimers()
|
||||
}
|
||||
|
||||
void
|
||||
ServerLobbyThread::HandleRead(SessionId sessionId, const boost::system::error_code& error, size_t bytesRead)
|
||||
ServerLobbyThread::HandleRead(SessionId sessionId, const boost::system::error_code &error, size_t bytesRead)
|
||||
{
|
||||
// Find the session.
|
||||
SessionWrapper session = m_sessionManager.GetSessionById(sessionId);
|
||||
@@ -949,11 +949,11 @@ ServerLobbyThread::HandleNetPacketCreateGame(SessionWrapper session, const NetPa
|
||||
session.playerData->GetUniqueId(),
|
||||
GetGui(),
|
||||
m_playerConfig));
|
||||
|
||||
MoveSessionToGame(*game, session);
|
||||
|
||||
game->Init();
|
||||
// Add game to list of games.
|
||||
InternalAddGame(game);
|
||||
|
||||
MoveSessionToGame(*game, session);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1043,7 +1043,7 @@ ServerLobbyThread::TimerRemoveGame()
|
||||
++next;
|
||||
boost::shared_ptr<ServerGame> tmpGame = i->second;
|
||||
if (!tmpGame->GetSessionManager().HasSessions())
|
||||
InternalRemoveGame(tmpGame); // This will delete the entry from the map.
|
||||
InternalRemoveGame(tmpGame); // This will delete the game.
|
||||
i = next;
|
||||
}
|
||||
}
|
||||
@@ -1154,6 +1154,7 @@ ServerLobbyThread::InternalRemoveGame(boost::shared_ptr<ServerGame> game)
|
||||
// Remove all sessions left in the game.
|
||||
game->ResetComputerPlayerList();
|
||||
game->RemoveAllSessions();
|
||||
game->Exit();
|
||||
// Notify all players.
|
||||
boost::shared_ptr<NetPacket> packet = CreateNetPacketGameListUpdate(game->GetId(), GAME_MODE_CLOSED);
|
||||
m_sessionManager.SendLobbyMsgToAllSessions(GetSender(), packet, SessionData::Established);
|
||||
|
||||
@@ -43,7 +43,7 @@ protected:
|
||||
|
||||
void InternalListen(unsigned serverPort, bool ipv6, bool sctp);
|
||||
void HandleAccept(boost::shared_ptr<boost::asio::ip::tcp::socket> acceptedSocket,
|
||||
const boost::system::error_code& error);
|
||||
const boost::system::error_code &error);
|
||||
|
||||
ServerCallback &GetCallback();
|
||||
|
||||
|
||||
@@ -43,6 +43,9 @@ public:
|
||||
ServerLobbyThread &lobbyThread, u_int32_t id, const std::string &name, const std::string &pwd, const GameData &gameData, unsigned adminPlayerId, GuiInterface &gui, ConfigFile *playerConfig);
|
||||
virtual ~ServerGame();
|
||||
|
||||
void Init();
|
||||
void Exit();
|
||||
|
||||
u_int32_t GetId() const;
|
||||
const std::string &GetName() const;
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@ protected:
|
||||
virtual void Main();
|
||||
void RegisterTimers();
|
||||
|
||||
void HandleRead(SessionId sessionId, const boost::system::error_code& error, size_t bytesRead);
|
||||
void HandleRead(SessionId sessionId, const boost::system::error_code &error, size_t bytesRead);
|
||||
void HandlePacket(SessionWrapper session, boost::shared_ptr<NetPacket> packet);
|
||||
void HandleNetPacketInit(SessionWrapper session, const NetPacketInit &tmpPacket);
|
||||
void HandleNetPacketAvatarHeader(SessionWrapper session, const NetPacketAvatarHeader &tmpPacket);
|
||||
|
||||
Reference in New Issue
Block a user