Sender thread is no longer a thread (part of boost::asio integration). Warning: Network games are still broken!
This commit is contained in:
@@ -378,12 +378,12 @@ void
|
|||||||
ClientThread::Main()
|
ClientThread::Main()
|
||||||
{
|
{
|
||||||
// Start sub-threads.
|
// Start sub-threads.
|
||||||
m_senderThread->Start();
|
|
||||||
m_avatarDownloader.reset(new DownloaderThread);
|
m_avatarDownloader.reset(new DownloaderThread);
|
||||||
m_avatarDownloader->Run();
|
m_avatarDownloader->Run();
|
||||||
SetState(CLIENT_INITIAL_STATE::Instance());
|
SetState(CLIENT_INITIAL_STATE::Instance());
|
||||||
|
|
||||||
// Main loop.
|
// Main loop.
|
||||||
|
boost::asio::io_service::work ioWork(*m_ioService);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
while (!ShouldTerminate())
|
while (!ShouldTerminate())
|
||||||
@@ -414,6 +414,9 @@ ClientThread::Main()
|
|||||||
}
|
}
|
||||||
if (IsSessionEstablished())
|
if (IsSessionEstablished())
|
||||||
SendPacketLoop();
|
SendPacketLoop();
|
||||||
|
m_ioService->poll();
|
||||||
|
GetContext().GetSessionData()->GetSender().Process();
|
||||||
|
Thread::Msleep(10);
|
||||||
}
|
}
|
||||||
} catch (const PokerTHException &e)
|
} catch (const PokerTHException &e)
|
||||||
{
|
{
|
||||||
@@ -422,8 +425,6 @@ ClientThread::Main()
|
|||||||
// Terminate sub-threads.
|
// Terminate sub-threads.
|
||||||
m_avatarDownloader->SignalTermination();
|
m_avatarDownloader->SignalTermination();
|
||||||
m_avatarDownloader->Join(DOWNLOADER_THREAD_TERMINATE_TIMEOUT);
|
m_avatarDownloader->Join(DOWNLOADER_THREAD_TERMINATE_TIMEOUT);
|
||||||
m_senderThread->SignalStop();
|
|
||||||
m_senderThread->WaitStop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -100,24 +100,6 @@ SenderThread::~SenderThread()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
SenderThread::Start()
|
|
||||||
{
|
|
||||||
Run();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
SenderThread::SignalStop()
|
|
||||||
{
|
|
||||||
SignalTermination();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
SenderThread::WaitStop()
|
|
||||||
{
|
|
||||||
Join(SENDER_THREAD_TERMINATE_TIMEOUT);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
SenderThread::Send(boost::shared_ptr<SessionData> session, boost::shared_ptr<NetPacket> packet)
|
SenderThread::Send(boost::shared_ptr<SessionData> session, boost::shared_ptr<NetPacket> packet)
|
||||||
{
|
{
|
||||||
@@ -190,73 +172,66 @@ SenderThread::SignalSessionTerminated(unsigned sessionId)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SenderThread::Main()
|
SenderThread::Process()
|
||||||
{
|
{
|
||||||
boost::asio::io_service::work ioWork(*m_ioService);
|
// Close sessions if they were destructed.
|
||||||
while (!ShouldTerminate())
|
|
||||||
{
|
{
|
||||||
// Close sessions if they were destructed.
|
boost::mutex::scoped_lock lock(m_removedSessionsMutex);
|
||||||
|
if (!m_removedSessions.empty())
|
||||||
{
|
{
|
||||||
boost::mutex::scoped_lock lock(m_removedSessionsMutex);
|
SessionIdList newRemovedSessions;
|
||||||
if (!m_removedSessions.empty())
|
SessionIdList::iterator i = m_removedSessions.begin();
|
||||||
|
SessionIdList::iterator end = m_removedSessions.end();
|
||||||
|
|
||||||
|
boost::mutex::scoped_lock lock(m_sendQueueMapMutex);
|
||||||
|
|
||||||
|
while (i != end)
|
||||||
{
|
{
|
||||||
SessionIdList newRemovedSessions;
|
SendQueueMap::iterator pos = m_sendQueueMap.find(*i);
|
||||||
SessionIdList::iterator i = m_removedSessions.begin();
|
if (pos != m_sendQueueMap.end())
|
||||||
SessionIdList::iterator end = m_removedSessions.end();
|
|
||||||
|
|
||||||
boost::mutex::scoped_lock lock(m_sendQueueMapMutex);
|
|
||||||
|
|
||||||
while (i != end)
|
|
||||||
{
|
{
|
||||||
SendQueueMap::iterator pos = m_sendQueueMap.find(*i);
|
// Remove session if no write is in progress, else wait.
|
||||||
if (pos != m_sendQueueMap.end())
|
bool shouldDelete;
|
||||||
{
|
{
|
||||||
// Remove session if no write is in progress, else wait.
|
boost::mutex::scoped_lock lock(pos->second->dataMutex);
|
||||||
bool shouldDelete;
|
shouldDelete = (!pos->second->writeInProgress && pos->second->list.empty());
|
||||||
{
|
|
||||||
boost::mutex::scoped_lock lock(pos->second->dataMutex);
|
|
||||||
shouldDelete = (!pos->second->writeInProgress && pos->second->list.empty());
|
|
||||||
}
|
|
||||||
if (shouldDelete)
|
|
||||||
m_sendQueueMap.erase(pos);
|
|
||||||
else
|
|
||||||
newRemovedSessions.push_back(*i);
|
|
||||||
}
|
}
|
||||||
++i;
|
if (shouldDelete)
|
||||||
|
m_sendQueueMap.erase(pos);
|
||||||
|
else
|
||||||
|
newRemovedSessions.push_back(*i);
|
||||||
}
|
}
|
||||||
m_removedSessions = newRemovedSessions;
|
++i;
|
||||||
|
}
|
||||||
|
m_removedSessions = newRemovedSessions;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Iterate through all changed sessions, and send data if needed.
|
||||||
|
bool sessionValid;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
sessionValid = false;
|
||||||
|
unsigned sessionId = 0;
|
||||||
|
|
||||||
|
{
|
||||||
|
boost::mutex::scoped_lock lock(m_changedSessionsMutex);
|
||||||
|
if (!m_changedSessions.empty())
|
||||||
|
{
|
||||||
|
sessionId = m_changedSessions.front();
|
||||||
|
m_changedSessions.pop_front();
|
||||||
|
sessionValid = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Iterate through all changed sessions, and send data if needed.
|
boost::shared_ptr<SendDataManager> tmpManager;
|
||||||
bool sessionValid;
|
if (sessionValid)
|
||||||
do
|
|
||||||
{
|
{
|
||||||
sessionValid = false;
|
boost::mutex::scoped_lock lock(m_sendQueueMapMutex);
|
||||||
unsigned sessionId = 0;
|
SendQueueMap::iterator pos = m_sendQueueMap.find(sessionId);
|
||||||
|
if (pos != m_sendQueueMap.end())
|
||||||
{
|
tmpManager = pos->second;
|
||||||
boost::mutex::scoped_lock lock(m_changedSessionsMutex);
|
}
|
||||||
if (!m_changedSessions.empty())
|
if (tmpManager)
|
||||||
{
|
tmpManager->AsyncSendNextPacket();
|
||||||
sessionId = m_changedSessions.front();
|
} while (sessionValid);
|
||||||
m_changedSessions.pop_front();
|
|
||||||
sessionValid = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
boost::shared_ptr<SendDataManager> tmpManager;
|
|
||||||
if (sessionValid)
|
|
||||||
{
|
|
||||||
boost::mutex::scoped_lock lock(m_sendQueueMapMutex);
|
|
||||||
SendQueueMap::iterator pos = m_sendQueueMap.find(sessionId);
|
|
||||||
if (pos != m_sendQueueMap.end())
|
|
||||||
tmpManager = pos->second;
|
|
||||||
}
|
|
||||||
if (tmpManager)
|
|
||||||
tmpManager->AsyncSendNextPacket();
|
|
||||||
} while (sessionValid);
|
|
||||||
|
|
||||||
m_ioService->poll();
|
|
||||||
Msleep(SEND_TIMEOUT_MSEC);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,6 +42,7 @@
|
|||||||
#define SERVER_CHECK_SESSION_TIMEOUTS_INTERVAL_MSEC 500
|
#define SERVER_CHECK_SESSION_TIMEOUTS_INTERVAL_MSEC 500
|
||||||
#define SERVER_REMOVE_GAME_INTERVAL_MSEC 100
|
#define SERVER_REMOVE_GAME_INTERVAL_MSEC 100
|
||||||
#define SERVER_REMOVE_PLAYER_INTERVAL_MSEC 100
|
#define SERVER_REMOVE_PLAYER_INTERVAL_MSEC 100
|
||||||
|
#define SERVER_UPDATE_AVATAR_LOCK_INTERVAL_MSEC 1000
|
||||||
|
|
||||||
#define SERVER_INIT_AVATAR_CLIENT_LOCK_SEC 30 // Forbid a client to send an additional avatar.
|
#define SERVER_INIT_AVATAR_CLIENT_LOCK_SEC 30 // Forbid a client to send an additional avatar.
|
||||||
|
|
||||||
@@ -493,24 +494,23 @@ ServerLobbyThread::GetNextGameId()
|
|||||||
void
|
void
|
||||||
ServerLobbyThread::Main()
|
ServerLobbyThread::Main()
|
||||||
{
|
{
|
||||||
|
boost::asio::io_service::work ioWork(*m_ioService);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Register all timers.
|
// Register all timers.
|
||||||
RegisterTimers();
|
RegisterTimers();
|
||||||
|
|
||||||
// Start send thread.
|
|
||||||
m_sender->Start();
|
|
||||||
|
|
||||||
while (!ShouldTerminate())
|
while (!ShouldTerminate())
|
||||||
{
|
{
|
||||||
// Process re-added sessions.
|
// Process re-added sessions.
|
||||||
NewSessionLoop();
|
NewSessionLoop();
|
||||||
// Resubscribe Lobby Messages if needed.
|
// Resubscribe Lobby Messages if needed.
|
||||||
ResubscribeLobbyMsgLoop();
|
ResubscribeLobbyMsgLoop();
|
||||||
// Update avatar limitation lock.
|
|
||||||
UpdateAvatarClientTimerLoop();
|
|
||||||
// Process timers.
|
// Process timers.
|
||||||
m_timerManager.Process();
|
m_timerManager.Process();
|
||||||
|
// Process asio service.
|
||||||
|
m_ioService->poll();
|
||||||
|
m_sender->Process();
|
||||||
Thread::Msleep(10);
|
Thread::Msleep(10);
|
||||||
}
|
}
|
||||||
} catch (const PokerTHException &e)
|
} catch (const PokerTHException &e)
|
||||||
@@ -524,9 +524,6 @@ ServerLobbyThread::Main()
|
|||||||
// Remove all sessions.
|
// Remove all sessions.
|
||||||
m_gameSessionManager.Clear();
|
m_gameSessionManager.Clear();
|
||||||
m_sessionManager.Clear();
|
m_sessionManager.Clear();
|
||||||
// Stop sender thread.
|
|
||||||
m_sender->SignalStop();
|
|
||||||
m_sender->WaitStop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -557,6 +554,11 @@ ServerLobbyThread::RegisterTimers()
|
|||||||
SERVER_SAVE_STATISTICS_INTERVAL_SEC * 1000,
|
SERVER_SAVE_STATISTICS_INTERVAL_SEC * 1000,
|
||||||
boost::bind(&ServerLobbyThread::TimerSaveStatisticsFile, this),
|
boost::bind(&ServerLobbyThread::TimerSaveStatisticsFile, this),
|
||||||
true);
|
true);
|
||||||
|
// Update the avatar upload locks.
|
||||||
|
m_timerManager.RegisterTimer(
|
||||||
|
SERVER_UPDATE_AVATAR_LOCK_INTERVAL_MSEC,
|
||||||
|
boost::bind(&ServerLobbyThread::TimerUpdateClientAvatarLock, this),
|
||||||
|
true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -1112,7 +1114,7 @@ ServerLobbyThread::ResubscribeLobbyMsgLoop()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ServerLobbyThread::UpdateAvatarClientTimerLoop()
|
ServerLobbyThread::TimerUpdateClientAvatarLock()
|
||||||
{
|
{
|
||||||
boost::mutex::scoped_lock lock(m_timerAvatarClientAddressMapMutex);
|
boost::mutex::scoped_lock lock(m_timerAvatarClientAddressMapMutex);
|
||||||
|
|
||||||
|
|||||||
@@ -29,13 +29,11 @@ class SenderInterface
|
|||||||
public:
|
public:
|
||||||
virtual ~SenderInterface();
|
virtual ~SenderInterface();
|
||||||
|
|
||||||
virtual void Start() = 0;
|
|
||||||
virtual void SignalStop() = 0;
|
|
||||||
virtual void WaitStop() = 0;
|
|
||||||
|
|
||||||
virtual void Send(boost::shared_ptr<SessionData> session, boost::shared_ptr<NetPacket> packet) = 0;
|
virtual void Send(boost::shared_ptr<SessionData> session, boost::shared_ptr<NetPacket> packet) = 0;
|
||||||
virtual void Send(boost::shared_ptr<SessionData> session, const NetPacketList &packetList) = 0;
|
virtual void Send(boost::shared_ptr<SessionData> session, const NetPacketList &packetList) = 0;
|
||||||
|
|
||||||
|
virtual void Process() = 0;
|
||||||
|
|
||||||
virtual void SignalSessionTerminated(unsigned sessionId) = 0;
|
virtual void SignalSessionTerminated(unsigned sessionId) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+3
-10
@@ -21,28 +21,24 @@
|
|||||||
#ifndef _SENDERTHREAD_H_
|
#ifndef _SENDERTHREAD_H_
|
||||||
#define _SENDERTHREAD_H_
|
#define _SENDERTHREAD_H_
|
||||||
|
|
||||||
#include <core/thread.h>
|
|
||||||
#include <net/senderinterface.h>
|
#include <net/senderinterface.h>
|
||||||
#include <net/netpacket.h>
|
#include <net/netpacket.h>
|
||||||
#include <net/sendercallback.h>
|
#include <net/sendercallback.h>
|
||||||
|
|
||||||
class SessionData;
|
class SessionData;
|
||||||
class SendDataManager;
|
class SendDataManager;
|
||||||
#define SENDER_THREAD_TERMINATE_TIMEOUT THREAD_WAIT_INFINITE
|
|
||||||
|
|
||||||
class SenderThread : public Thread, public SenderInterface
|
class SenderThread : public SenderInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SenderThread(SenderCallback &cb, boost::shared_ptr<boost::asio::io_service> ioService);
|
SenderThread(SenderCallback &cb, boost::shared_ptr<boost::asio::io_service> ioService);
|
||||||
virtual ~SenderThread();
|
virtual ~SenderThread();
|
||||||
|
|
||||||
virtual void Start();
|
|
||||||
virtual void SignalStop();
|
|
||||||
virtual void WaitStop();
|
|
||||||
|
|
||||||
virtual void Send(boost::shared_ptr<SessionData> session, boost::shared_ptr<NetPacket> packet);
|
virtual void Send(boost::shared_ptr<SessionData> session, boost::shared_ptr<NetPacket> packet);
|
||||||
virtual void Send(boost::shared_ptr<SessionData> session, const NetPacketList &packetList);
|
virtual void Send(boost::shared_ptr<SessionData> session, const NetPacketList &packetList);
|
||||||
|
|
||||||
|
virtual void Process();
|
||||||
|
|
||||||
virtual void SignalSessionTerminated(unsigned sessionId);
|
virtual void SignalSessionTerminated(unsigned sessionId);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -50,9 +46,6 @@ protected:
|
|||||||
|
|
||||||
typedef std::map<SessionId, boost::shared_ptr<SendDataManager> > SendQueueMap;
|
typedef std::map<SessionId, boost::shared_ptr<SendDataManager> > SendQueueMap;
|
||||||
|
|
||||||
// Main function of the thread.
|
|
||||||
virtual void Main();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
SenderCallback &m_callback;
|
SenderCallback &m_callback;
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ protected:
|
|||||||
void TimerRemoveGame();
|
void TimerRemoveGame();
|
||||||
void TimerRemovePlayer();
|
void TimerRemovePlayer();
|
||||||
void ResubscribeLobbyMsgLoop();
|
void ResubscribeLobbyMsgLoop();
|
||||||
void UpdateAvatarClientTimerLoop();
|
void TimerUpdateClientAvatarLock();
|
||||||
void TimerCheckSessionTimeouts();
|
void TimerCheckSessionTimeouts();
|
||||||
void TimerCleanupAvatarCache();
|
void TimerCleanupAvatarCache();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user