diff --git a/src/net/clientcontext.h b/src/net/clientcontext.h index 27ff6e62..0e338841 100644 --- a/src/net/clientcontext.h +++ b/src/net/clientcontext.h @@ -24,10 +24,8 @@ #include #include #include -#include #include -class ClientSenderCallback; class ClientContext : public NetContext { @@ -36,9 +34,9 @@ public: virtual ~ClientContext(); virtual SOCKET GetSocket() const; - void SetSocket(SOCKET sockfd); boost::shared_ptr GetSessionData() const; + void SetSessionData(boost::shared_ptr sessionData); int GetProtocol() const {return m_protocol;} void SetProtocol(int protocol) @@ -114,9 +112,6 @@ private: std::string m_cacheDir; bool m_hasSubscribedLobbyMsg; ReceiveBuffer m_receiveBuffer; - boost::shared_ptr m_senderCallback; - boost::shared_ptr m_senderThread; - boost::shared_ptr m_ioService; }; #endif diff --git a/src/net/clientthread.h b/src/net/clientthread.h index edda11cc..87cf2650 100644 --- a/src/net/clientthread.h +++ b/src/net/clientthread.h @@ -22,6 +22,7 @@ #define _CLIENTTHREAD_H_ #include +#include #include #include #include @@ -112,6 +113,7 @@ protected: const ClientContext &GetContext() const; ClientContext &GetContext(); + void SetContextSocket(SOCKET s); ClientState &GetState(); void SetState(ClientState &newState); @@ -164,6 +166,9 @@ protected: private: + boost::shared_ptr m_ioService; + boost::shared_ptr m_senderCallback; + NetPacketList m_outPacketList; mutable boost::mutex m_outPacketListMutex; @@ -207,6 +212,8 @@ private: mutable boost::mutex m_curStatsMutex; ServerStats m_curStats; + boost::shared_ptr m_senderThread; + friend class AbstractClientStateReceiving; friend class ClientStateInit; friend class ClientStateStartResolve; diff --git a/src/net/common/clientcontext.cpp b/src/net/common/clientcontext.cpp index d9b1f4ae..b4e7914c 100644 --- a/src/net/common/clientcontext.cpp +++ b/src/net/common/clientcontext.cpp @@ -18,24 +18,6 @@ ***************************************************************************/ #include -#include - -class ClientSenderCallback : public SenderCallback, public SessionDataCallback -{ -public: - ClientSenderCallback() {} - virtual ~ClientSenderCallback() {} - - virtual void SignalNetError(SessionId /*session*/, int /*errorID*/, int /*osErrorID*/) - { - } - - virtual void SignalSessionTerminated(unsigned /*session*/) - { - } - -private: -}; ClientContext::ClientContext() @@ -43,17 +25,10 @@ ClientContext::ClientContext() m_hasSubscribedLobbyMsg(true) { bzero(&m_clientSockaddr, sizeof(m_clientSockaddr)); - m_ioService.reset(new boost::asio::io_service()); - m_senderCallback.reset(new ClientSenderCallback()); - m_senderThread.reset(new SenderThread(*m_senderCallback, m_ioService)); - m_senderThread->Start(); } ClientContext::~ClientContext() { - m_senderThread->SignalStop(); - m_senderThread->WaitStop(); - m_senderThread.reset(); m_sessionData.reset(); } @@ -64,15 +39,15 @@ ClientContext::GetSocket() const return m_sessionData->GetSocket(); } -void -ClientContext::SetSocket(SOCKET sockfd) -{ - m_sessionData.reset(new SessionData(sockfd, SESSION_ID_GENERIC, m_senderThread, *m_senderCallback, *m_ioService)); -} - boost::shared_ptr ClientContext::GetSessionData() const { return m_sessionData; } +void +ClientContext::SetSessionData(boost::shared_ptr sessionData) +{ + m_sessionData = sessionData; +} + diff --git a/src/net/common/clientstate.cpp b/src/net/common/clientstate.cpp index 93a6fe8b..ce094f39 100644 --- a/src/net/common/clientstate.cpp +++ b/src/net/common/clientstate.cpp @@ -86,7 +86,7 @@ ClientStateInit::Process(ClientThread &client) if (context.GetServerPort() < 1024) throw ClientException(__FILE__, __LINE__, ERR_SOCK_INVALID_PORT, 0); - context.SetSocket(socket(context.GetAddrFamily(), SOCK_STREAM, context.GetProtocol())); + client.SetContextSocket(socket(context.GetAddrFamily(), SOCK_STREAM, context.GetProtocol())); if (!IS_VALID_SOCKET(context.GetSocket())) throw ClientException(__FILE__, __LINE__, ERR_SOCK_CREATION_FAILED, SOCKET_ERRNO()); diff --git a/src/net/common/clientthread.cpp b/src/net/common/clientthread.cpp index d678fbc3..ab792b9d 100644 --- a/src/net/common/clientthread.cpp +++ b/src/net/common/clientthread.cpp @@ -42,13 +42,33 @@ using namespace std; +class ClientSenderCallback : public SenderCallback, public SessionDataCallback +{ +public: + ClientSenderCallback() {} + virtual ~ClientSenderCallback() {} + + virtual void SignalNetError(SessionId /*session*/, int /*errorID*/, int /*osErrorID*/) + { + } + + virtual void SignalSessionTerminated(unsigned /*session*/) + { + } + +private: +}; + ClientThread::ClientThread(GuiInterface &gui, AvatarManager &avatarManager) : m_curState(NULL), m_gui(gui), m_avatarManager(avatarManager), m_curGameId(0), m_curGameNum(1), m_guiPlayerId(0), m_sessionEstablished(false) { + m_ioService.reset(new boost::asio::io_service()); m_context.reset(new ClientContext); m_receiver.reset(new ReceiverHelper); myQtToolsInterface.reset(CreateQtToolsWrapper()); + m_senderCallback.reset(new ClientSenderCallback()); + m_senderThread.reset(new SenderThread(*m_senderCallback, m_ioService)); } ClientThread::~ClientThread() @@ -334,6 +354,8 @@ ClientThread::GetAvatarManager() void ClientThread::Main() { + // Start sub-threads. + m_senderThread->Start(); if (!GetContext().GetAvatarServerAddr().empty()) { m_avatarDownloader.reset(new DownloaderThread); @@ -341,6 +363,7 @@ ClientThread::Main() } SetState(CLIENT_INITIAL_STATE::Instance()); + // Main loop. try { while (!ShouldTerminate()) @@ -376,12 +399,15 @@ ClientThread::Main() { GetCallback().SignalNetClientError(e.GetErrorId(), e.GetOsErrorCode()); } + // Terminate sub-threads. if (m_avatarDownloader) { m_avatarDownloader->SignalTermination(); m_avatarDownloader->Join(DOWNLOADER_THREAD_TERMINATE_TIMEOUT); m_avatarDownloader.reset(); } + m_senderThread->SignalStop(); + m_senderThread->WaitStop(); } void @@ -657,6 +683,17 @@ ClientThread::GetContext() return *m_context; } +void +ClientThread::SetContextSocket(SOCKET s) +{ + GetContext().SetSessionData(boost::shared_ptr(new SessionData( + s, + SESSION_ID_GENERIC, + m_senderThread, + *m_senderCallback, + *m_ioService))); +} + ClientState & ClientThread::GetState() { diff --git a/src/net/common/sessiondata.cpp b/src/net/common/sessiondata.cpp index a0989862..24a227c8 100644 --- a/src/net/common/sessiondata.cpp +++ b/src/net/common/sessiondata.cpp @@ -32,7 +32,13 @@ SessionData::SessionData(SOCKET sockfd, SessionId id, boost::shared_ptrcancel(); + // We are shutting down, so ignore any error. + try + { + m_socket->cancel(); + } catch(...) + { + } } SessionId