Core/Netcode: Fix a possible infinite loop after 829be0b82 (which was accidentally merged in this morning)
This commit is contained in:
@@ -224,7 +224,17 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
|
|||||||
WorldPacket* packet = NULL;
|
WorldPacket* packet = NULL;
|
||||||
//! Delete packet after processing by default
|
//! Delete packet after processing by default
|
||||||
bool deletePacket = true;
|
bool deletePacket = true;
|
||||||
while (m_Socket && !m_Socket->IsClosed() && _recvQueue.next(packet, updater))
|
//! To prevent infinite loop
|
||||||
|
bool delayedPackets = false;
|
||||||
|
WorldPacket* firstDelayedPacket = NULL;
|
||||||
|
//! If _recvQueue.peek() == firstDelayedPacket it means that in this Update call, we've processed all
|
||||||
|
//! *properly timed* packets, and we're now at the part of the queue where we find
|
||||||
|
//! delayed packets that were re-enqueued due to improper timing. To prevent an infinite
|
||||||
|
//! loop caused by re-enqueueing the same packets over and over again, we stop updating this session
|
||||||
|
//! and continue updating others. The re-enqueued packets will be handled in the next Update call for this session.
|
||||||
|
while (m_Socket && !m_Socket->IsClosed() &&
|
||||||
|
!_recvQueue.empty() && _recvQueue.peek(true) != firstDelayedPacket &&
|
||||||
|
_recvQueue.next(packet, updater))
|
||||||
{
|
{
|
||||||
if (packet->GetOpcode() >= NUM_MSG_TYPES)
|
if (packet->GetOpcode() >= NUM_MSG_TYPES)
|
||||||
{
|
{
|
||||||
@@ -246,9 +256,11 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
|
|||||||
//! the client to be in world yet. We will re-add the packets to the bottom of the queue and process them later.
|
//! the client to be in world yet. We will re-add the packets to the bottom of the queue and process them later.
|
||||||
if (!m_playerRecentlyLogout)
|
if (!m_playerRecentlyLogout)
|
||||||
{
|
{
|
||||||
|
//! Prevent infinite loop
|
||||||
|
if (!firstDelayedPacket)
|
||||||
|
firstDelayedPacket = packet;
|
||||||
//! Because checking a bool is faster than reallocating memory
|
//! Because checking a bool is faster than reallocating memory
|
||||||
deletePacket = false;
|
deletePacket = false;
|
||||||
//! Re-enqueue
|
|
||||||
QueuePacket(packet);
|
QueuePacket(packet);
|
||||||
//! Log
|
//! Log
|
||||||
sLog->outDebug(LOG_FILTER_NETWORKIO, "Re-enqueueing packet with opcode %s (0x%.4X) with with status STATUS_LOGGEDIN. "
|
sLog->outDebug(LOG_FILTER_NETWORKIO, "Re-enqueueing packet with opcode %s (0x%.4X) with with status STATUS_LOGGEDIN. "
|
||||||
|
|||||||
@@ -98,13 +98,16 @@ namespace ACE_Based
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Peeks at the top of the queue. Remember to unlock after use.
|
//! Peeks at the top of the queue. Check if the queue is empty before calling! Remember to unlock after use if autoUnlock == false.
|
||||||
T& peek()
|
T& peek(bool autoUnlock = false)
|
||||||
{
|
{
|
||||||
lock();
|
lock();
|
||||||
|
|
||||||
T& result = _queue.front();
|
T& result = _queue.front();
|
||||||
|
|
||||||
|
if (autoUnlock)
|
||||||
|
unlock();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user