Core/PacketIO: Requeue packets handled with STATUS_LOGGEDIN received before player is fully loaded in one step after packet processing loop - reduces used locks from 3 per packet to 1 per packet

(cherry picked from commit 8086a39210)
This commit is contained in:
Shauren
2016-02-22 20:02:26 +01:00
parent 67aa8cabce
commit 9fc5c4bc41
2 changed files with 13 additions and 12 deletions

View File

@@ -57,6 +57,14 @@ public:
unlock();
}
//! Adds items back to front of the queue
template<class Iterator>
void readd(Iterator begin, Iterator end)
{
std::lock_guard<std::mutex> lock(_lock);
_queue.insert(_queue.begin(), begin, end);
}
//! Gets the next result in the queue, if any.
bool next(T& result)
{

View File

@@ -272,17 +272,11 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
WorldPacket* packet = NULL;
//! Delete packet after processing by default
bool deletePacket = true;
//! To prevent infinite loop
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.
std::vector<WorldPacket*> requeuePackets;
uint32 processedPackets = 0;
time_t currentTime = time(NULL);
while (m_Socket && !_recvQueue.empty() && _recvQueue.peek(true) != firstDelayedPacket && _recvQueue.next(packet, updater))
while (m_Socket && _recvQueue.next(packet, updater))
{
if (packet->GetOpcode() >= NUM_MSG_TYPES)
{
@@ -305,10 +299,7 @@ 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.
if (!m_playerRecentlyLogout)
{
//! Prevent infinite loop
if (!firstDelayedPacket)
firstDelayedPacket = packet;
//! Because checking a bool is faster than reallocating memory
requeuePackets.push_back(packet);
deletePacket = false;
QueuePacket(packet);
//! Log
@@ -400,6 +391,8 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
break;
}
_recvQueue.readd(requeuePackets.begin(), requeuePackets.end());
if (m_Socket && m_Socket->IsOpen() && _warden)
_warden->Update();