From 22edd63ddea55d964dc2655b060b14e5aa9e0dfb Mon Sep 17 00:00:00 2001 From: lotodore Date: Mon, 15 Jun 2009 22:34:07 +0000 Subject: [PATCH] Further paranoia changes to prevent timer callbacks from occurring in an uncontrolled state. --- src/net/clientstate.h | 19 ++++++++++++++++++- src/net/common/clientstate.cpp | 10 +++++++++- src/net/common/clientthread.cpp | 3 +++ src/net/common/servergame.cpp | 5 ++--- src/net/common/servergamestate.cpp | 10 ++++++++++ src/net/servergamestate.h | 24 ++++++++++++++++++++++++ 6 files changed, 66 insertions(+), 5 deletions(-) diff --git a/src/net/clientstate.h b/src/net/clientstate.h index f6843fc9..74d3da6b 100644 --- a/src/net/clientstate.h +++ b/src/net/clientstate.h @@ -26,6 +26,7 @@ #include #define CLIENT_INITIAL_STATE ClientStateInit +#define CLIENT_FINAL_STATE ClientStateFinal class ClientThread; class ClientCallback; @@ -42,7 +43,7 @@ public: virtual void Enter(boost::shared_ptr client) = 0; virtual void Exit(boost::shared_ptr client) = 0; - virtual void HandlePacket(boost::shared_ptr /*client*/, boost::shared_ptr /*tmpPacket*/) = 0; + virtual void HandlePacket(boost::shared_ptr client, boost::shared_ptr tmpPacket) = 0; }; // State: Initialization. @@ -401,4 +402,20 @@ protected: static void ResetPlayerSets(Game &curGame); }; +class ClientStateFinal : public ClientState +{ +public: + static ClientStateFinal &Instance(); + virtual ~ClientStateFinal() {} + + virtual void Enter(boost::shared_ptr /*client*/) {} + virtual void Exit(boost::shared_ptr /*client*/) {} + + virtual void HandlePacket(boost::shared_ptr /*client*/, boost::shared_ptr /*tmpPacket*/) {} + +protected: + // Protected constructor - this is a singleton. + ClientStateFinal() {} +}; + #endif diff --git a/src/net/common/clientstate.cpp b/src/net/common/clientstate.cpp index 88750fba..d32b0ff4 100644 --- a/src/net/common/clientstate.cpp +++ b/src/net/common/clientstate.cpp @@ -1156,7 +1156,7 @@ ClientStateSynchronizeStart::TimerLoop(const boost::system::error_code& ec, boos } void -ClientStateSynchronizeStart::InternalHandlePacket(boost::shared_ptr client, boost::shared_ptr tmpPacket) +ClientStateSynchronizeStart::InternalHandlePacket(boost::shared_ptr /*client*/, boost::shared_ptr tmpPacket) { if (tmpPacket->ToNetPacketGameStart()) throw ClientException(__FILE__, __LINE__, ERR_NET_START_TIMEOUT, 0); @@ -1630,3 +1630,11 @@ ClientStateRunHand::ResetPlayerSets(Game &curGame) } } +//----------------------------------------------------------------------------- + +ClientStateFinal & +ClientStateFinal::Instance() +{ + static ClientStateFinal state; + return state; +} diff --git a/src/net/common/clientthread.cpp b/src/net/common/clientthread.cpp index 88808416..ce3c2902 100644 --- a/src/net/common/clientthread.cpp +++ b/src/net/common/clientthread.cpp @@ -444,6 +444,9 @@ ClientThread::Main() // Execute remaining ready handlers. m_ioService->reset(); m_ioService->poll(); + // Set a state which does not do anything. + SetState(CLIENT_FINAL_STATE::Instance()); + } catch (const PokerTHException &e) { GetCallback().SignalNetClientError(e.GetErrorId(), e.GetOsErrorCode()); diff --git a/src/net/common/servergame.cpp b/src/net/common/servergame.cpp index fc46ec9c..a625639e 100644 --- a/src/net/common/servergame.cpp +++ b/src/net/common/servergame.cpp @@ -69,8 +69,7 @@ void ServerGame::Exit() { m_voteKickTimer.cancel(); - if (m_curState) - m_curState->Exit(shared_from_this()); + SetState(ServerGameStateFinal::Instance()); } u_int32_t @@ -131,7 +130,7 @@ ServerGame::RemoveAllSessions() void ServerGame::TimerVoteKick(const boost::system::error_code &ec) { - if (!ec) + if (!ec && m_curState != &ServerGameStateFinal::Instance()) { // Check whether someone should be kicked, or whether a vote kick should be aborted. // Only one vote kick can be active at a time. diff --git a/src/net/common/servergamestate.cpp b/src/net/common/servergamestate.cpp index 2c640a96..ea5f48f8 100644 --- a/src/net/common/servergamestate.cpp +++ b/src/net/common/servergamestate.cpp @@ -1193,3 +1193,13 @@ ServerGameStateWaitPlayerAction::TimerTimeout(const boost::system::error_code &e //----------------------------------------------------------------------------- +ServerGameStateFinal ServerGameStateFinal::s_state; + +ServerGameStateFinal & +ServerGameStateFinal::Instance() +{ + return s_state; +} + +//----------------------------------------------------------------------------- + diff --git a/src/net/servergamestate.h b/src/net/servergamestate.h index bb42f498..57d2d238 100644 --- a/src/net/servergamestate.h +++ b/src/net/servergamestate.h @@ -176,6 +176,30 @@ private: static ServerGameStateWaitPlayerAction s_state; }; +class ServerGameStateFinal : public ServerGameState +{ +public: + static ServerGameStateFinal &Instance(); + + virtual ~ServerGameStateFinal() {} + virtual void Enter(boost::shared_ptr server) {} + virtual void Exit(boost::shared_ptr server) {} + + virtual void NotifyGameAdminChanged(boost::shared_ptr server) {} + + // Handling of a new session. + virtual void HandleNewSession(boost::shared_ptr server, SessionWrapper session) {} + + // Main processing function of the current state. + virtual int ProcessPacket(boost::shared_ptr server, SessionWrapper session, boost::shared_ptr packet) {} + +protected: + ServerGameStateFinal() {} + +private: + static ServerGameStateFinal s_state; +}; + #ifdef _MSC_VER #pragma warning(pop) #endif