Core/Netcode: Fix a possible infinite loop after 829be0b82 (which was accidentally merged in this morning)

This commit is contained in:
Machiavelli
2011-12-19 21:12:35 +01:00
parent d1378a9c94
commit 8e0be985fd
2 changed files with 19 additions and 4 deletions
+14 -2
View File
@@ -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. "
+5 -2
View File
@@ -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;
} }