1
0
Fork 0

ClientHandle no longer queues chat messages.

It is no longer needed to queue chat messages, because the protocol is parsed within the Tick thread itself, without holding any SocketThread CS.
This commit is contained in:
madmaxoft 2013-08-14 20:08:05 +02:00
parent e2ff4a2e5c
commit 0af2a0b08c
2 changed files with 17 additions and 56 deletions

View File

@ -921,11 +921,24 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, c
void cClientHandle::HandleChat(const AString & a_Message)
{
// We need to process messages in the Tick thread, to avoid deadlocks resulting from player-commands being processed
// in the SocketThread and waiting for acquiring the ChunkMap CS with Plugin CS locked
// We no longer need to postpone message processing, because the messages already arrive in the Tick thread
cCSLock Lock(m_CSMessages);
m_PendingMessages.push_back(a_Message);
// If a command, perform it:
AString Message(a_Message);
if (cRoot::Get()->GetServer()->Command(*this, Message))
{
return;
}
// Not a command, broadcast as a simple message:
AString Msg;
Printf(Msg, "<%s%s%s> %s",
m_Player->GetColor().c_str(),
m_Player->GetName().c_str(),
cChatColor::White.c_str(),
Message.c_str()
);
m_Player->GetWorld()->BroadcastChat(Msg);
}
@ -1446,9 +1459,6 @@ void cClientHandle::Tick(float a_Dt)
m_CurrentExplosionTick = (m_CurrentExplosionTick + 1) % ARRAYCOUNT(m_NumExplosionsPerTick);
m_RunningSumExplosions -= m_NumExplosionsPerTick[m_CurrentExplosionTick];
m_NumExplosionsPerTick[m_CurrentExplosionTick] = 0;
// Process the queued messages:
ProcessPendingMessages();
}
@ -2096,46 +2106,6 @@ void cClientHandle::AddWantedChunk(int a_ChunkX, int a_ChunkZ)
void cClientHandle::ProcessPendingMessages(void)
{
while (true)
{
AString Message;
// Extract one message from the PendingMessages buffer:
{
cCSLock Lock(m_CSMessages);
if (m_PendingMessages.empty())
{
// No more messages in the buffer, bail out
return;
}
Message = m_PendingMessages.front();
m_PendingMessages.pop_front();
} // Lock(m_CSMessages)
// If a command, perform it:
if (cRoot::Get()->GetServer()->Command(*this, Message))
{
continue;
}
// Not a command, broadcast as a simple message:
AString Msg;
Printf(Msg, "<%s%s%s> %s",
m_Player->GetColor().c_str(),
m_Player->GetName().c_str(),
cChatColor::White.c_str(),
Message.c_str()
);
m_Player->GetWorld()->BroadcastChat(Msg);
} // while (true)
}
void cClientHandle::PacketBufferFull(void)
{
// Too much data in the incoming queue, the server is probably too busy, kick the client:

View File

@ -288,12 +288,6 @@ private:
/// Running sum of m_NumExplosionsPerTick[]
int m_RunningSumExplosions;
/// Lock for the m_PendingMessages buffer
cCriticalSection m_CSMessages;
/// Buffer for received messages to be processed in the Tick thread
AStringList m_PendingMessages;
static int s_ClientCount;
int m_UniqueID;
@ -320,9 +314,6 @@ private:
/// Handles the block placing packet when it is a real block placement (not block-using, item-using or eating)
void HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, cItemHandler & a_ItemHandler);
/// Processes the messages in m_PendingMessages; called from the Tick thread
void ProcessPendingMessages(void);
// cSocketThreads::cCallback overrides:
virtual void DataReceived (const char * a_Data, int a_Size) override; // Data is received from the client
virtual void GetOutgoingData(AString & a_Data) override; // Data can be sent to client