aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2014-07-27 17:46:46 +0200
committerShauren <shauren.trinity@gmail.com>2014-07-27 17:46:46 +0200
commit6f272ea5b7d6551844aa1a1f748cee5c79b746f3 (patch)
tree82fd15487be93bad4a2674f10fc4cd0694bd9007
parent8a05231994342bc826fa98f3f1df741cc14e19f7 (diff)
Core/Network: Optimized packet sending by removing unneccessary memory copying
-rw-r--r--src/server/authserver/Server/AuthSession.h2
-rw-r--r--src/server/game/Calendar/CalendarMgr.cpp2
-rw-r--r--src/server/game/Calendar/CalendarMgr.h2
-rw-r--r--src/server/game/Entities/Object/Object.cpp2
-rw-r--r--src/server/game/Entities/Object/Updates/UpdateData.h8
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp6
-rw-r--r--src/server/game/Handlers/CombatHandler.cpp6
-rw-r--r--src/server/game/Maps/Map.cpp2
-rw-r--r--src/server/game/Maps/Map.h2
-rw-r--r--src/server/game/Scripting/ScriptMgr.cpp24
-rw-r--r--src/server/game/Scripting/ScriptMgr.h6
-rw-r--r--src/server/game/Server/WorldSession.cpp12
-rw-r--r--src/server/game/Server/WorldSession.h4
-rw-r--r--src/server/game/Server/WorldSocket.cpp13
-rw-r--r--src/server/game/Server/WorldSocket.h58
-rw-r--r--src/server/shared/Packets/ByteBuffer.h30
-rw-r--r--src/server/shared/Packets/WorldPacket.h22
-rw-r--r--src/server/shared/Threading/ProducerConsumerQueue.h14
18 files changed, 162 insertions, 53 deletions
diff --git a/src/server/authserver/Server/AuthSession.h b/src/server/authserver/Server/AuthSession.h
index 822f3c334fc..14129d76fd8 100644
--- a/src/server/authserver/Server/AuthSession.h
+++ b/src/server/authserver/Server/AuthSession.h
@@ -20,9 +20,9 @@
#define __AUTHSESSION_H__
#include "Common.h"
+#include "ByteBuffer.h"
#include "Socket.h"
#include "BigNumber.h"
-#include "ByteBuffer.h"
#include <memory>
#include <boost/asio/ip/tcp.hpp>
diff --git a/src/server/game/Calendar/CalendarMgr.cpp b/src/server/game/Calendar/CalendarMgr.cpp
index 03d65fb134d..92f19c0adeb 100644
--- a/src/server/game/Calendar/CalendarMgr.cpp
+++ b/src/server/game/Calendar/CalendarMgr.cpp
@@ -636,7 +636,7 @@ void CalendarMgr::SendCalendarCommandResult(uint64 guid, CalendarError err, char
}
}
-void CalendarMgr::SendPacketToAllEventRelatives(WorldPacket packet, CalendarEvent const& calendarEvent)
+void CalendarMgr::SendPacketToAllEventRelatives(WorldPacket& packet, CalendarEvent const& calendarEvent)
{
// Send packet to all guild members
if (calendarEvent.IsGuildEvent() || calendarEvent.IsGuildAnnouncement())
diff --git a/src/server/game/Calendar/CalendarMgr.h b/src/server/game/Calendar/CalendarMgr.h
index e238119defb..9bdb7c0a187 100644
--- a/src/server/game/Calendar/CalendarMgr.h
+++ b/src/server/game/Calendar/CalendarMgr.h
@@ -329,7 +329,7 @@ class CalendarMgr
void SendCalendarClearPendingAction(uint64 guid);
void SendCalendarCommandResult(uint64 guid, CalendarError err, char const* param = NULL);
- void SendPacketToAllEventRelatives(WorldPacket packet, CalendarEvent const& calendarEvent);
+ void SendPacketToAllEventRelatives(WorldPacket& packet, CalendarEvent const& calendarEvent);
};
#define sCalendarMgr CalendarMgr::instance()
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index 23af4a70d3e..dfc0c438662 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -548,7 +548,7 @@ void Object::BuildFieldsUpdate(Player* player, UpdateDataMapType& data_map) cons
if (iter == data_map.end())
{
- std::pair<UpdateDataMapType::iterator, bool> p = data_map.insert(UpdateDataMapType::value_type(player, UpdateData()));
+ std::pair<UpdateDataMapType::iterator, bool> p = data_map.emplace(player, UpdateData());
ASSERT(p.second);
iter = p.first;
}
diff --git a/src/server/game/Entities/Object/Updates/UpdateData.h b/src/server/game/Entities/Object/Updates/UpdateData.h
index 16bdec46aba..1ec86192fab 100644
--- a/src/server/game/Entities/Object/Updates/UpdateData.h
+++ b/src/server/game/Entities/Object/Updates/UpdateData.h
@@ -53,6 +53,11 @@ class UpdateData
{
public:
UpdateData();
+ UpdateData(UpdateData&& right) : m_blockCount(right.m_blockCount),
+ m_outOfRangeGUIDs(std::move(right.m_outOfRangeGUIDs)),
+ m_data(std::move(right.m_data))
+ {
+ }
void AddOutOfRangeGUID(std::set<uint64>& guids);
void AddOutOfRangeGUID(uint64 guid);
@@ -69,6 +74,9 @@ class UpdateData
ByteBuffer m_data;
void Compress(void* dst, uint32 *dst_size, void* src, int src_size);
+
+ UpdateData(UpdateData const& right) = delete;
+ UpdateData& operator=(UpdateData const& right) = delete;
};
#endif
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 9472fba6572..f5b72b845a5 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -2223,7 +2223,11 @@ void Unit::SendMeleeAttackStop(Unit* victim)
{
WorldPacket data(SMSG_ATTACKSTOP, (8+8+4));
data.append(GetPackGUID());
- data.append(victim ? victim->GetPackGUID() : 0);
+ if (victim)
+ data.append(victim->GetPackGUID());
+ else
+ data << uint8(0);
+
data << uint32(0); //! Can also take the value 0x01, which seems related to updating rotation
SendMessageToSet(&data, true);
TC_LOG_DEBUG("entities.unit", "WORLD: Sent SMSG_ATTACKSTOP");
diff --git a/src/server/game/Handlers/CombatHandler.cpp b/src/server/game/Handlers/CombatHandler.cpp
index 47ffc2578bd..e4d749d9ab0 100644
--- a/src/server/game/Handlers/CombatHandler.cpp
+++ b/src/server/game/Handlers/CombatHandler.cpp
@@ -93,7 +93,11 @@ void WorldSession::SendAttackStop(Unit const* enemy)
{
WorldPacket data(SMSG_ATTACKSTOP, (8+8+4)); // we guess size
data.append(GetPlayer()->GetPackGUID());
- data.append(enemy ? enemy->GetPackGUID() : 0); // must be packed guid
+ if (enemy)
+ data.append(enemy->GetPackGUID());
+ else
+ data << uint8(0);
+
data << uint32(0); // unk, can be 1 also
SendPacket(&data);
}
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index fbc33418e47..b0164b77f1c 100644
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -2682,7 +2682,7 @@ uint32 Map::GetPlayersCountExceptGMs() const
return count;
}
-void Map::SendToPlayers(WorldPacket const* data) const
+void Map::SendToPlayers(WorldPacket* data) const
{
for (MapRefManager::const_iterator itr = m_mapRefManager.begin(); itr != m_mapRefManager.end(); ++itr)
itr->GetSource()->GetSession()->SendPacket(data);
diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h
index b431ca4ba17..70198cb20a3 100644
--- a/src/server/game/Maps/Map.h
+++ b/src/server/game/Maps/Map.h
@@ -423,7 +423,7 @@ class Map : public GridRefManager<NGridType>
void AddWorldObject(WorldObject* obj) { i_worldObjects.insert(obj); }
void RemoveWorldObject(WorldObject* obj) { i_worldObjects.erase(obj); }
- void SendToPlayers(WorldPacket const* data) const;
+ void SendToPlayers(WorldPacket* data) const;
typedef MapRefManager PlayerList;
PlayerList const& GetPlayers() const { return m_mapRefManager; }
diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp
index 1b91ed1690c..0d1983ab463 100644
--- a/src/server/game/Scripting/ScriptMgr.cpp
+++ b/src/server/game/Scripting/ScriptMgr.cpp
@@ -414,25 +414,37 @@ void ScriptMgr::OnSocketClose(std::shared_ptr<WorldSocket> socket, bool wasNew)
FOREACH_SCRIPT(ServerScript)->OnSocketClose(socket, wasNew);
}
-void ScriptMgr::OnPacketReceive(std::shared_ptr<WorldSocket> socket, WorldPacket packet)
+void ScriptMgr::OnPacketReceive(std::shared_ptr<WorldSocket> socket, WorldPacket const& packet)
{
ASSERT(socket);
- FOREACH_SCRIPT(ServerScript)->OnPacketReceive(socket, packet);
+ if (SCR_REG_LST(ServerScript).empty())
+ return;
+
+ WorldPacket copy(packet);
+ FOREACH_SCRIPT(ServerScript)->OnPacketReceive(socket, copy);
}
-void ScriptMgr::OnPacketSend(std::shared_ptr<WorldSocket> socket, WorldPacket packet)
+void ScriptMgr::OnPacketSend(std::shared_ptr<WorldSocket> socket, WorldPacket const& packet)
{
ASSERT(socket);
- FOREACH_SCRIPT(ServerScript)->OnPacketSend(socket, packet);
+ if (SCR_REG_LST(ServerScript).empty())
+ return;
+
+ WorldPacket copy(packet);
+ FOREACH_SCRIPT(ServerScript)->OnPacketSend(socket, copy);
}
-void ScriptMgr::OnUnknownPacketReceive(std::shared_ptr<WorldSocket> socket, WorldPacket packet)
+void ScriptMgr::OnUnknownPacketReceive(std::shared_ptr<WorldSocket> socket, WorldPacket const& packet)
{
ASSERT(socket);
- FOREACH_SCRIPT(ServerScript)->OnUnknownPacketReceive(socket, packet);
+ if (SCR_REG_LST(ServerScript).empty())
+ return;
+
+ WorldPacket copy(packet);
+ FOREACH_SCRIPT(ServerScript)->OnUnknownPacketReceive(socket, copy);
}
void ScriptMgr::OnOpenStateChange(bool open)
diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h
index 325a0743d79..0b5813a7f58 100644
--- a/src/server/game/Scripting/ScriptMgr.h
+++ b/src/server/game/Scripting/ScriptMgr.h
@@ -910,9 +910,9 @@ class ScriptMgr
void OnNetworkStop();
void OnSocketOpen(std::shared_ptr<WorldSocket> socket);
void OnSocketClose(std::shared_ptr<WorldSocket> socket, bool wasNew);
- void OnPacketReceive(std::shared_ptr<WorldSocket> socket, WorldPacket packet);
- void OnPacketSend(std::shared_ptr<WorldSocket> socket, WorldPacket packet);
- void OnUnknownPacketReceive(std::shared_ptr<WorldSocket> socket, WorldPacket packet);
+ void OnPacketReceive(std::shared_ptr<WorldSocket> socket, WorldPacket const& packet);
+ void OnPacketSend(std::shared_ptr<WorldSocket> socket, WorldPacket const& packet);
+ void OnUnknownPacketReceive(std::shared_ptr<WorldSocket> socket, WorldPacket const& packet);
public: /* WorldScript */
diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp
index eb83a5f55be..279e69a4267 100644
--- a/src/server/game/Server/WorldSession.cpp
+++ b/src/server/game/Server/WorldSession.cpp
@@ -186,7 +186,7 @@ uint32 WorldSession::GetGuidLow() const
}
/// Send a packet to the client
-void WorldSession::SendPacket(WorldPacket const* packet)
+void WorldSession::SendPacket(WorldPacket* packet)
{
if (!m_Socket)
return;
@@ -288,7 +288,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
{
TC_LOG_ERROR("network.opcode", "Received non-existed opcode %s from %s", GetOpcodeNameForLogging(packet->GetOpcode()).c_str()
, GetPlayerInfo().c_str());
- sScriptMgr->OnUnknownPacketReceive(m_Socket, WorldPacket(*packet));
+ sScriptMgr->OnUnknownPacketReceive(m_Socket, *packet);
}
else
{
@@ -318,7 +318,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
}
else if (_player->IsInWorld())
{
- sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet));
+ sScriptMgr->OnPacketReceive(m_Socket, *packet);
(this->*opHandle.handler)(*packet);
LogUnprocessedTail(packet);
}
@@ -331,7 +331,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
else
{
// not expected _player or must checked in packet handler
- sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet));
+ sScriptMgr->OnPacketReceive(m_Socket, *packet);
(this->*opHandle.handler)(*packet);
LogUnprocessedTail(packet);
}
@@ -343,7 +343,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
LogUnexpectedOpcode(packet, "STATUS_TRANSFER", "the player is still in world");
else
{
- sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet));
+ sScriptMgr->OnPacketReceive(m_Socket, *packet);
(this->*opHandle.handler)(*packet);
LogUnprocessedTail(packet);
}
@@ -361,7 +361,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
if (packet->GetOpcode() == CMSG_CHAR_ENUM)
m_playerRecentlyLogout = false;
- sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet));
+ sScriptMgr->OnPacketReceive(m_Socket, *packet);
(this->*opHandle.handler)(*packet);
LogUnprocessedTail(packet);
break;
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index 7ad43907355..d5b2146ae79 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -178,7 +178,7 @@ class CharacterCreateInfo
protected:
CharacterCreateInfo(std::string const& name, uint8 race, uint8 cclass, uint8 gender, uint8 skin, uint8 face, uint8 hairStyle, uint8 hairColor, uint8 facialHair, uint8 outfitId,
WorldPacket& data) : Name(name), Race(race), Class(cclass), Gender(gender), Skin(skin), Face(face), HairStyle(hairStyle), HairColor(hairColor), FacialHair(facialHair),
- OutfitId(outfitId), Data(data), CharCount(0)
+ OutfitId(outfitId), Data(std::move(data)), CharCount(0)
{ }
/// User specified variables
@@ -222,7 +222,7 @@ class WorldSession
void ReadMovementInfo(WorldPacket& data, MovementInfo* mi);
void WriteMovementInfo(WorldPacket* data, MovementInfo* mi);
- void SendPacket(WorldPacket const* packet);
+ void SendPacket(WorldPacket* packet);
void SendNotification(const char *format, ...) ATTR_PRINTF(2, 3);
void SendNotification(uint32 string_id, ...);
void SendPetNameInvalid(uint32 error, std::string const& name, DeclinedName *declinedName);
diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp
index f078b2acc15..ea0bfc234bf 100644
--- a/src/server/game/Server/WorldSocket.cpp
+++ b/src/server/game/Server/WorldSocket.cpp
@@ -18,7 +18,6 @@
#include <memory>
#include "WorldSocket.h"
-#include "ServerPktHeader.h"
#include "BigNumber.h"
#include "Opcodes.h"
#include "ScriptMgr.h"
@@ -140,7 +139,7 @@ void WorldSocket::ReadDataHandler(boost::system::error_code error, size_t transf
CloseSocket();
}
-void WorldSocket::AsyncWrite(WorldPacket const& packet)
+void WorldSocket::AsyncWrite(WorldPacket& packet)
{
if (sPacketLog->CanLogPacket())
sPacketLog->LogPacket(packet, SERVER_TO_CLIENT);
@@ -149,18 +148,12 @@ void WorldSocket::AsyncWrite(WorldPacket const& packet)
ServerPktHeader header(packet.size() + 2, packet.GetOpcode());
- std::vector<uint8> data(header.getHeaderLength() + packet.size());
- std::memcpy(data.data(), header.header, header.getHeaderLength());
-
- if (!packet.empty())
- std::memcpy(&data[header.getHeaderLength()], packet.contents(), packet.size());
-
std::lock_guard<std::mutex> guard(_writeLock);
bool needsWriteStart = _writeQueue.empty();
- _authCrypt.EncryptSend(data.data(), header.getHeaderLength());
+ _authCrypt.EncryptSend(header.header, header.getHeaderLength());
- _writeQueue.push(std::move(data));
+ _writeQueue.emplace(header, std::move(packet));
if (needsWriteStart)
AsyncWrite(_writeQueue.front());
diff --git a/src/server/game/Server/WorldSocket.h b/src/server/game/Server/WorldSocket.h
index f355308ff7a..1fa08c2b5f1 100644
--- a/src/server/game/Server/WorldSocket.h
+++ b/src/server/game/Server/WorldSocket.h
@@ -19,14 +19,26 @@
#ifndef __WORLDSOCKET_H__
#define __WORLDSOCKET_H__
+// Forward declare buffer function here - Socket.h must know about it
+struct WorldPacketBuffer;
+namespace boost
+{
+ namespace asio
+ {
+ WorldPacketBuffer const& buffer(WorldPacketBuffer const& buf);
+ }
+}
+
#include "Common.h"
#include "AuthCrypt.h"
+#include "ServerPktHeader.h"
#include "Socket.h"
#include "Util.h"
#include "WorldPacket.h"
#include "WorldSession.h"
#include <chrono>
#include <boost/asio/ip/tcp.hpp>
+#include <boost/asio/buffer.hpp>
using boost::asio::ip::tcp;
@@ -40,9 +52,49 @@ struct ClientPktHeader
#pragma pack(pop)
-class WorldSocket : public Socket<WorldSocket, std::vector<uint8> >
+struct WorldPacketBuffer
+{
+ typedef boost::asio::const_buffer value_type;
+
+ typedef boost::asio::const_buffer const* const_iterator;
+
+ WorldPacketBuffer(ServerPktHeader header, WorldPacket&& packet) : _header(header), _packet(std::move(packet))
+ {
+ _buffers[0] = boost::asio::const_buffer(_header.header, _header.getHeaderLength());
+ if (!_packet.empty())
+ _buffers[1] = boost::asio::const_buffer(_packet.contents(), _packet.size());
+ }
+
+ const_iterator begin() const
+ {
+ return _buffers;
+ }
+
+ const_iterator end() const
+ {
+ return _buffers + (_packet.empty() ? 1 : 2);
+ }
+
+private:
+ boost::asio::const_buffer _buffers[2];
+ ServerPktHeader _header;
+ WorldPacket _packet;
+};
+
+namespace boost
+{
+ namespace asio
+ {
+ inline WorldPacketBuffer const& buffer(WorldPacketBuffer const& buf)
+ {
+ return buf;
+ }
+ }
+}
+
+class WorldSocket : public Socket<WorldSocket, WorldPacketBuffer>
{
- typedef Socket<WorldSocket, std::vector<uint8> > Base;
+ typedef Socket<WorldSocket, WorldPacketBuffer> Base;
public:
WorldSocket(tcp::socket&& socket);
@@ -53,7 +105,7 @@ public:
void Start() override;
using Base::AsyncWrite;
- void AsyncWrite(WorldPacket const& packet);
+ void AsyncWrite(WorldPacket& packet);
protected:
void ReadHeaderHandler(boost::system::error_code error, size_t transferedBytes) override;
diff --git a/src/server/shared/Packets/ByteBuffer.h b/src/server/shared/Packets/ByteBuffer.h
index 311143b384c..9744904f0dc 100644
--- a/src/server/shared/Packets/ByteBuffer.h
+++ b/src/server/shared/Packets/ByteBuffer.h
@@ -81,12 +81,28 @@ class ByteBuffer
_storage.reserve(reserve);
}
- // copy constructor
- ByteBuffer(const ByteBuffer &buf) : _rpos(buf._rpos), _wpos(buf._wpos),
- _storage(buf._storage)
+ ByteBuffer(ByteBuffer&& buf) : _rpos(buf._rpos), _wpos(buf._wpos),
+ _storage(std::move(buf._storage))
{
}
+ ByteBuffer(ByteBuffer const& right) : _rpos(right._rpos), _wpos(right._wpos),
+ _storage(right._storage)
+ {
+ }
+
+ ByteBuffer& operator=(ByteBuffer const& right)
+ {
+ if (this != &right)
+ {
+ _rpos = right._rpos;
+ _wpos = right._wpos;
+ _storage = right._storage;
+ }
+
+ return *this;
+ }
+
virtual ~ByteBuffer() { }
void clear()
@@ -383,18 +399,18 @@ class ByteBuffer
return *this;
}
- uint8 * contents()
+ uint8* contents()
{
if (_storage.empty())
throw ByteBufferException();
- return &_storage[0];
+ return _storage.data();
}
- const uint8 *contents() const
+ uint8 const* contents() const
{
if (_storage.empty())
throw ByteBufferException();
- return &_storage[0];
+ return _storage.data();
}
size_t size() const { return _storage.size(); }
diff --git a/src/server/shared/Packets/WorldPacket.h b/src/server/shared/Packets/WorldPacket.h
index 6703c5ed2ea..8851b9f3e45 100644
--- a/src/server/shared/Packets/WorldPacket.h
+++ b/src/server/shared/Packets/WorldPacket.h
@@ -29,12 +29,28 @@ class WorldPacket : public ByteBuffer
WorldPacket() : ByteBuffer(0), m_opcode(0)
{
}
+
explicit WorldPacket(uint16 opcode, size_t res=200) : ByteBuffer(res), m_opcode(opcode) { }
- // copy constructor
- WorldPacket(const WorldPacket &packet) : ByteBuffer(packet), m_opcode(packet.m_opcode)
+
+ WorldPacket(WorldPacket&& packet) : ByteBuffer(std::move(packet)), m_opcode(packet.m_opcode)
+ {
+ }
+
+ WorldPacket(WorldPacket const& right) : ByteBuffer(right), m_opcode(right.m_opcode)
{
}
+ WorldPacket& operator=(WorldPacket const& right)
+ {
+ if (this != &right)
+ {
+ m_opcode = right.m_opcode;
+ ByteBuffer::operator =(right);
+ }
+
+ return *this;
+ }
+
void Initialize(uint16 opcode, size_t newres=200)
{
clear();
@@ -48,5 +64,5 @@ class WorldPacket : public ByteBuffer
protected:
uint16 m_opcode;
};
-#endif
+#endif
diff --git a/src/server/shared/Threading/ProducerConsumerQueue.h b/src/server/shared/Threading/ProducerConsumerQueue.h
index 45a1cbc692a..1fee1d0685f 100644
--- a/src/server/shared/Threading/ProducerConsumerQueue.h
+++ b/src/server/shared/Threading/ProducerConsumerQueue.h
@@ -22,12 +22,11 @@
#include <mutex>
#include <queue>
#include <atomic>
+#include <type_traits>
template <typename T>
class ProducerConsumerQueue
{
- static_assert(std::is_pointer<T>::value, "T for ProducerConsumerQueue must be a pointer");
-
private:
std::mutex _queueLock;
std::queue<T> _queue;
@@ -94,7 +93,7 @@ public:
{
T& value = _queue.front();
- delete value;
+ DeleteQueuedObject(value);
_queue.pop();
}
@@ -105,8 +104,13 @@ public:
_condition.notify_all();
}
-};
-#endif
+private:
+ template<typename E = T>
+ typename std::enable_if<std::is_pointer<E>::value>::type DeleteQueuedObject(E& obj) { delete obj; }
+ template<typename E = T>
+ typename std::enable_if<!std::is_pointer<E>::value>::type DeleteQueuedObject(E const& /*packet*/) { }
+};
+#endif