mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 05:57:29 +02:00
SendQueue first draft
This commit is contained in:
parent
b364553ea5
commit
dce1fc6855
2 changed files with 150 additions and 0 deletions
82
libraries/networking/src/udt/SendQueue.cpp
Normal file
82
libraries/networking/src/udt/SendQueue.cpp
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
//
|
||||||
|
// SendQueue.cpp
|
||||||
|
// libraries/networking/src/udt
|
||||||
|
//
|
||||||
|
// Created by Clement on 7/21/15.
|
||||||
|
// Copyright 2015 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "SendQueue.h"
|
||||||
|
|
||||||
|
#include <QtCore/QThread>
|
||||||
|
#include <QtCore/QTimer>
|
||||||
|
|
||||||
|
#include <SharedUtil.h>
|
||||||
|
|
||||||
|
namespace udt {
|
||||||
|
|
||||||
|
std::unique_ptr<SendQueue> SendQueue::create() {
|
||||||
|
return std::unique_ptr<SendQueue>(new SendQueue());
|
||||||
|
}
|
||||||
|
|
||||||
|
SendQueue::SendQueue() {
|
||||||
|
_sendTimer.reset(new QTimer(this));
|
||||||
|
_sendTimer->setSingleShot(true);
|
||||||
|
QObject::connect(_sendTimer.get(), &QTimer::timeout, this, &SendQueue::sendNextPacket);
|
||||||
|
|
||||||
|
_packetSendPeriod = DEFAULT_SEND_PERIOD;
|
||||||
|
_lastSendTimestamp = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SendQueue::queuePacket(std::unique_ptr<Packet> packet) {
|
||||||
|
QWriteLocker locker(&_packetsLock);
|
||||||
|
_packets.push_back(std::move(packet));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SendQueue::start() {
|
||||||
|
// We need to make sure this is called on the right thread
|
||||||
|
if (thread() != QThread::currentThread()) {
|
||||||
|
QMetaObject::invokeMethod(this, "start", Qt::QueuedConnection);
|
||||||
|
}
|
||||||
|
// This will send a packet and fire the send timer
|
||||||
|
sendNextPacket();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SendQueue::stop() {
|
||||||
|
// We need to make sure this is called on the right thread
|
||||||
|
if (thread() != QThread::currentThread()) {
|
||||||
|
QMetaObject::invokeMethod(this, "stop", Qt::QueuedConnection);
|
||||||
|
}
|
||||||
|
// Stopping the timer will stop the sending of packets
|
||||||
|
_sendTimer->stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SendQueue::sendNextPacket() {
|
||||||
|
// Record timing
|
||||||
|
auto sendTime = msecTimestampNow(); // msec
|
||||||
|
_lastSendTimestamp = sendTime;
|
||||||
|
// TODO send packet
|
||||||
|
|
||||||
|
// Insert the packet we have just sent in the sent list
|
||||||
|
_sentPackets[_nextPacket->readSequenceNumber()].swap(_nextPacket);
|
||||||
|
Q_ASSERT(!_nextPacket); // There should be no packet where we inserted
|
||||||
|
|
||||||
|
{ // Grab next packet to be sent
|
||||||
|
QWriteLocker locker(&_packetsLock);
|
||||||
|
_nextPacket.swap(_packets.front());
|
||||||
|
_packets.pop_front();
|
||||||
|
}
|
||||||
|
|
||||||
|
// How long before next packet send
|
||||||
|
auto timeToSleep = (sendTime + _packetSendPeriod) - msecTimestampNow(); // msec
|
||||||
|
if (timeToSleep > 0) {
|
||||||
|
_sendTimer->start(timeToSleep);
|
||||||
|
} else {
|
||||||
|
_sendTimer->start(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
68
libraries/networking/src/udt/SendQueue.h
Normal file
68
libraries/networking/src/udt/SendQueue.h
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
//
|
||||||
|
// SendQueue.h
|
||||||
|
// libraries/networking/src/udt
|
||||||
|
//
|
||||||
|
// Created by Clement on 7/21/15.
|
||||||
|
// Copyright 2015 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef hifi_SendQueue_h
|
||||||
|
#define hifi_SendQueue_h
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QReadWriteLock>
|
||||||
|
|
||||||
|
#include "Packet.h"
|
||||||
|
|
||||||
|
class QTimer;
|
||||||
|
|
||||||
|
namespace udt {
|
||||||
|
|
||||||
|
class SendQueue : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
static const int DEFAULT_SEND_PERIOD = 16; // msec
|
||||||
|
|
||||||
|
static std::unique_ptr<SendQueue> create();
|
||||||
|
|
||||||
|
void queuePacket(std::unique_ptr<Packet> packet);
|
||||||
|
int getQueueSize() const { return _packets.size(); }
|
||||||
|
|
||||||
|
quint64 getLastSendTimestamp() const { return _lastSendTimestamp; }
|
||||||
|
|
||||||
|
int getPacketSendPeriod() const { return _packetSendPeriod; }
|
||||||
|
void setPacketSendPeriod(int newPeriod) { _packetSendPeriod = newPeriod; }
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void start();
|
||||||
|
void stop();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void sendNextPacket();
|
||||||
|
|
||||||
|
private:
|
||||||
|
SendQueue();
|
||||||
|
SendQueue(SendQueue& other) = delete;
|
||||||
|
SendQueue(SendQueue&& other) = delete;
|
||||||
|
|
||||||
|
QReadWriteLock _packetsLock; // Protects the packets to be sent list.
|
||||||
|
std::list<std::unique_ptr<Packet>> _packets; // List of packets to be sent
|
||||||
|
std::unique_ptr<Packet> _nextPacket;
|
||||||
|
|
||||||
|
std::unique_ptr<QTimer> _sendTimer; // Send timer
|
||||||
|
std::atomic<int> _packetSendPeriod; // Interval between two packet send envent in msec
|
||||||
|
std::atomic<quint64> _lastSendTimestamp; // Record last time of packet departure
|
||||||
|
|
||||||
|
std::unordered_map<int, std::unique_ptr<Packet>> _sentPackets; // Packets waiting for ACK.
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // hifi_SendQueue_h
|
Loading…
Reference in a new issue