Fixed nasty cleanup crash on Windows.

This commit is contained in:
lotodore
2009-03-21 10:28:27 +00:00
parent 4a8f1e7692
commit ebac9c9574
6 changed files with 59 additions and 39 deletions
+1 -6
View File
@@ -24,10 +24,8 @@
#include <net/netcontext.h> #include <net/netcontext.h>
#include <net/receivebuffer.h> #include <net/receivebuffer.h>
#include <net/sessiondata.h> #include <net/sessiondata.h>
#include <net/senderinterface.h>
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
class ClientSenderCallback;
class ClientContext : public NetContext class ClientContext : public NetContext
{ {
@@ -36,9 +34,9 @@ public:
virtual ~ClientContext(); virtual ~ClientContext();
virtual SOCKET GetSocket() const; virtual SOCKET GetSocket() const;
void SetSocket(SOCKET sockfd);
boost::shared_ptr<SessionData> GetSessionData() const; boost::shared_ptr<SessionData> GetSessionData() const;
void SetSessionData(boost::shared_ptr<SessionData> sessionData);
int GetProtocol() const int GetProtocol() const
{return m_protocol;} {return m_protocol;}
void SetProtocol(int protocol) void SetProtocol(int protocol)
@@ -114,9 +112,6 @@ private:
std::string m_cacheDir; std::string m_cacheDir;
bool m_hasSubscribedLobbyMsg; bool m_hasSubscribedLobbyMsg;
ReceiveBuffer m_receiveBuffer; ReceiveBuffer m_receiveBuffer;
boost::shared_ptr<ClientSenderCallback> m_senderCallback;
boost::shared_ptr<SenderInterface> m_senderThread;
boost::shared_ptr<boost::asio::io_service> m_ioService;
}; };
#endif #endif
+7
View File
@@ -22,6 +22,7 @@
#define _CLIENTTHREAD_H_ #define _CLIENTTHREAD_H_
#include <core/thread.h> #include <core/thread.h>
#include <net/senderinterface.h>
#include <guiinterface.h> #include <guiinterface.h>
#include <playerdata.h> #include <playerdata.h>
#include <gamedata.h> #include <gamedata.h>
@@ -112,6 +113,7 @@ protected:
const ClientContext &GetContext() const; const ClientContext &GetContext() const;
ClientContext &GetContext(); ClientContext &GetContext();
void SetContextSocket(SOCKET s);
ClientState &GetState(); ClientState &GetState();
void SetState(ClientState &newState); void SetState(ClientState &newState);
@@ -164,6 +166,9 @@ protected:
private: private:
boost::shared_ptr<boost::asio::io_service> m_ioService;
boost::shared_ptr<ClientSenderCallback> m_senderCallback;
NetPacketList m_outPacketList; NetPacketList m_outPacketList;
mutable boost::mutex m_outPacketListMutex; mutable boost::mutex m_outPacketListMutex;
@@ -207,6 +212,8 @@ private:
mutable boost::mutex m_curStatsMutex; mutable boost::mutex m_curStatsMutex;
ServerStats m_curStats; ServerStats m_curStats;
boost::shared_ptr<SenderInterface> m_senderThread;
friend class AbstractClientStateReceiving; friend class AbstractClientStateReceiving;
friend class ClientStateInit; friend class ClientStateInit;
friend class ClientStateStartResolve; friend class ClientStateStartResolve;
+6 -31
View File
@@ -18,24 +18,6 @@
***************************************************************************/ ***************************************************************************/
#include <net/clientcontext.h> #include <net/clientcontext.h>
#include <net/senderthread.h>
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() ClientContext::ClientContext()
@@ -43,17 +25,10 @@ ClientContext::ClientContext()
m_hasSubscribedLobbyMsg(true) m_hasSubscribedLobbyMsg(true)
{ {
bzero(&m_clientSockaddr, sizeof(m_clientSockaddr)); 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() ClientContext::~ClientContext()
{ {
m_senderThread->SignalStop();
m_senderThread->WaitStop();
m_senderThread.reset();
m_sessionData.reset(); m_sessionData.reset();
} }
@@ -64,15 +39,15 @@ ClientContext::GetSocket() const
return m_sessionData->GetSocket(); 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<SessionData> boost::shared_ptr<SessionData>
ClientContext::GetSessionData() const ClientContext::GetSessionData() const
{ {
return m_sessionData; return m_sessionData;
} }
void
ClientContext::SetSessionData(boost::shared_ptr<SessionData> sessionData)
{
m_sessionData = sessionData;
}
+1 -1
View File
@@ -86,7 +86,7 @@ ClientStateInit::Process(ClientThread &client)
if (context.GetServerPort() < 1024) if (context.GetServerPort() < 1024)
throw ClientException(__FILE__, __LINE__, ERR_SOCK_INVALID_PORT, 0); 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())) if (!IS_VALID_SOCKET(context.GetSocket()))
throw ClientException(__FILE__, __LINE__, ERR_SOCK_CREATION_FAILED, SOCKET_ERRNO()); throw ClientException(__FILE__, __LINE__, ERR_SOCK_CREATION_FAILED, SOCKET_ERRNO());
+37
View File
@@ -42,13 +42,33 @@
using namespace std; 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) ClientThread::ClientThread(GuiInterface &gui, AvatarManager &avatarManager)
: m_curState(NULL), m_gui(gui), m_avatarManager(avatarManager), : m_curState(NULL), m_gui(gui), m_avatarManager(avatarManager),
m_curGameId(0), m_curGameNum(1), m_guiPlayerId(0), m_sessionEstablished(false) 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_context.reset(new ClientContext);
m_receiver.reset(new ReceiverHelper); m_receiver.reset(new ReceiverHelper);
myQtToolsInterface.reset(CreateQtToolsWrapper()); myQtToolsInterface.reset(CreateQtToolsWrapper());
m_senderCallback.reset(new ClientSenderCallback());
m_senderThread.reset(new SenderThread(*m_senderCallback, m_ioService));
} }
ClientThread::~ClientThread() ClientThread::~ClientThread()
@@ -334,6 +354,8 @@ ClientThread::GetAvatarManager()
void void
ClientThread::Main() ClientThread::Main()
{ {
// Start sub-threads.
m_senderThread->Start();
if (!GetContext().GetAvatarServerAddr().empty()) if (!GetContext().GetAvatarServerAddr().empty())
{ {
m_avatarDownloader.reset(new DownloaderThread); m_avatarDownloader.reset(new DownloaderThread);
@@ -341,6 +363,7 @@ ClientThread::Main()
} }
SetState(CLIENT_INITIAL_STATE::Instance()); SetState(CLIENT_INITIAL_STATE::Instance());
// Main loop.
try try
{ {
while (!ShouldTerminate()) while (!ShouldTerminate())
@@ -376,12 +399,15 @@ ClientThread::Main()
{ {
GetCallback().SignalNetClientError(e.GetErrorId(), e.GetOsErrorCode()); GetCallback().SignalNetClientError(e.GetErrorId(), e.GetOsErrorCode());
} }
// Terminate sub-threads.
if (m_avatarDownloader) if (m_avatarDownloader)
{ {
m_avatarDownloader->SignalTermination(); m_avatarDownloader->SignalTermination();
m_avatarDownloader->Join(DOWNLOADER_THREAD_TERMINATE_TIMEOUT); m_avatarDownloader->Join(DOWNLOADER_THREAD_TERMINATE_TIMEOUT);
m_avatarDownloader.reset(); m_avatarDownloader.reset();
} }
m_senderThread->SignalStop();
m_senderThread->WaitStop();
} }
void void
@@ -657,6 +683,17 @@ ClientThread::GetContext()
return *m_context; return *m_context;
} }
void
ClientThread::SetContextSocket(SOCKET s)
{
GetContext().SetSessionData(boost::shared_ptr<SessionData>(new SessionData(
s,
SESSION_ID_GENERIC,
m_senderThread,
*m_senderCallback,
*m_ioService)));
}
ClientState & ClientState &
ClientThread::GetState() ClientThread::GetState()
{ {
+7 -1
View File
@@ -32,7 +32,13 @@ SessionData::SessionData(SOCKET sockfd, SessionId id, boost::shared_ptr<SenderIn
SessionData::~SessionData() SessionData::~SessionData()
{ {
m_callback.SignalSessionTerminated(m_id); m_callback.SignalSessionTerminated(m_id);
m_socket->cancel(); // We are shutting down, so ignore any error.
try
{
m_socket->cancel();
} catch(...)
{
}
} }
SessionId SessionId