Use one channel per packet list

This commit is contained in:
Atlante45 2015-09-24 13:08:04 +02:00
parent 3db99f50e5
commit 48ff912dd2
3 changed files with 43 additions and 16 deletions

View file

@ -11,12 +11,10 @@
#include "PacketQueue.h" #include "PacketQueue.h"
#include "Packet.h"
#include "PacketList.h" #include "PacketList.h"
using namespace udt; using namespace udt;
MessageNumber PacketQueue::getNextMessageNumber() { MessageNumber PacketQueue::getNextMessageNumber() {
static const MessageNumber MAX_MESSAGE_NUMBER = MessageNumber(1) << MESSAGE_NUMBER_BITS; static const MessageNumber MAX_MESSAGE_NUMBER = MessageNumber(1) << MESSAGE_NUMBER_BITS;
_currentMessageNumber = (_currentMessageNumber + 1) % MAX_MESSAGE_NUMBER; _currentMessageNumber = (_currentMessageNumber + 1) % MAX_MESSAGE_NUMBER;
@ -25,28 +23,50 @@ MessageNumber PacketQueue::getNextMessageNumber() {
bool PacketQueue::isEmpty() const { bool PacketQueue::isEmpty() const {
LockGuard locker(_packetsLock); LockGuard locker(_packetsLock);
return _packets.empty(); // Only the main channel and it is empty
return (_channels.size() == 1) && _channels.front().empty();
} }
PacketQueue::PacketPointer PacketQueue::takePacket() { PacketQueue::PacketPointer PacketQueue::takePacket() {
LockGuard locker(_packetsLock); LockGuard locker(_packetsLock);
if (!_packets.empty()) { if (isEmpty()) {
auto packet = std::move(_packets.front()); return PacketPointer();
_packets.pop_front();
return std::move(packet);
} }
return PacketPointer(); // Find next non empty channel
if (_channels[nextIndex()].empty()) {
nextIndex();
}
auto& channel = _channels[_currentIndex];
Q_ASSERT(!channel.empty());
// Take front packet
auto packet = std::move(channel.front());
channel.pop_front();
// Remove now empty channel (Don't remove the main channel)
if (channel.empty() && _currentIndex != 0) {
channel.swap(_channels.back());
_channels.pop_back();
--_currentIndex;
}
return std::move(packet);
}
unsigned int PacketQueue::nextIndex() {
_currentIndex = ++_currentIndex % _channels.size();
return _currentIndex;
} }
void PacketQueue::queuePacket(PacketPointer packet) { void PacketQueue::queuePacket(PacketPointer packet) {
LockGuard locker(_packetsLock); LockGuard locker(_packetsLock);
_packets.push_back(std::move(packet)); _channels.front().push_back(std::move(packet));
} }
void PacketQueue::queuePacketList(PacketListPointer packetList) { void PacketQueue::queuePacketList(PacketListPointer packetList) {
packetList->preparePackets(getNextMessageNumber()); packetList->preparePackets(getNextMessageNumber());
LockGuard locker(_packetsLock); LockGuard locker(_packetsLock);
_packets.splice(_packets.end(), packetList->_packets); _channels.push_back(std::move(packetList->_packets));
} }

View file

@ -13,12 +13,14 @@
#define hifi_PacketQueue_h #define hifi_PacketQueue_h
#include <list> #include <list>
#include <vector>
#include <memory> #include <memory>
#include <mutex> #include <mutex>
#include "Packet.h"
namespace udt { namespace udt {
class Packet;
class PacketList; class PacketList;
using MessageNumber = uint32_t; using MessageNumber = uint32_t;
@ -28,7 +30,8 @@ class PacketQueue {
using LockGuard = std::lock_guard<Mutex>; using LockGuard = std::lock_guard<Mutex>;
using PacketPointer = std::unique_ptr<Packet>; using PacketPointer = std::unique_ptr<Packet>;
using PacketListPointer = std::unique_ptr<PacketList>; using PacketListPointer = std::unique_ptr<PacketList>;
using PacketContainer = std::list<PacketPointer>; using Channel = std::list<PacketPointer>;
using Channels = std::vector<Channel>;
public: public:
void queuePacket(PacketPointer packet); void queuePacket(PacketPointer packet);
@ -37,14 +40,17 @@ public:
bool isEmpty() const; bool isEmpty() const;
PacketPointer takePacket(); PacketPointer takePacket();
MessageNumber getNextMessageNumber();
Mutex& getLock() { return _packetsLock; } Mutex& getLock() { return _packetsLock; }
private: private:
MessageNumber getNextMessageNumber();
unsigned int nextIndex();
MessageNumber _currentMessageNumber { 0 }; MessageNumber _currentMessageNumber { 0 };
mutable Mutex _packetsLock; // Protects the packets to be sent list. mutable Mutex _packetsLock; // Protects the packets to be sent.
PacketContainer _packets; // List of packets to be sent Channels _channels { 1 }; // One channel per packet list
unsigned int _currentIndex { 0 };
}; };
} }

View file

@ -296,6 +296,7 @@ bool SendQueue::maybeSendNewPacket() {
// grab the first packet we will send // grab the first packet we will send
std::unique_ptr<Packet> firstPacket = _packets.takePacket(); std::unique_ptr<Packet> firstPacket = _packets.takePacket();
Q_ASSERT(firstPacket);
std::unique_ptr<Packet> secondPacket; std::unique_ptr<Packet> secondPacket;
bool shouldSendPairTail = false; bool shouldSendPairTail = false;