diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/common/Threading/LockedQueue.h | 8 | ||||
-rw-r--r-- | src/server/game/Server/WorldSession.cpp | 23 |
2 files changed, 15 insertions, 16 deletions
diff --git a/src/common/Threading/LockedQueue.h b/src/common/Threading/LockedQueue.h index c6faaaf81ca..21a29d7e53b 100644 --- a/src/common/Threading/LockedQueue.h +++ b/src/common/Threading/LockedQueue.h @@ -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) { diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 0092a35c811..78e7bbfc180 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -341,17 +341,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[CONNECTION_TYPE_REALM] && !_recvQueue.empty() && _recvQueue.peek(true) != firstDelayedPacket && _recvQueue.next(packet, updater)) + while (m_Socket[CONNECTION_TYPE_REALM] && _recvQueue.next(packet, updater)) { ClientOpcodeHandler const* opHandle = opcodeTable[static_cast<OpcodeClient>(packet->GetOpcode())]; try @@ -366,15 +360,10 @@ 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 - TC_LOG_DEBUG("network", "Re-enqueueing packet with opcode %s with with status STATUS_LOGGEDIN. " - "Player is currently not in world yet.", GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())).c_str()); + TC_LOG_DEBUG("network", "Re-enqueueing packet with opcode %s with with status STATUS_LOGGEDIN. " + "Player is currently not in world yet.", GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())).c_str()); } } else if (_player->IsInWorld() && AntiDOS.EvaluateOpcode(*packet, currentTime)) @@ -465,6 +454,8 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater) break; } + _recvQueue.readd(requeuePackets.begin(), requeuePackets.end()); + if (m_Socket[CONNECTION_TYPE_REALM] && m_Socket[CONNECTION_TYPE_REALM]->IsOpen() && _warden) _warden->Update(); |