fix ATP SendQueue failure to receive after re-activity

This commit is contained in:
Stephen Birarda 2016-02-04 13:43:50 -08:00
parent 294a7ee9ad
commit 42e9a4ebf0
4 changed files with 23 additions and 9 deletions

View file

@ -82,8 +82,12 @@ void Connection::resetRTT() {
SendQueue& Connection::getSendQueue() { SendQueue& Connection::getSendQueue() {
if (!_sendQueue) { if (!_sendQueue) {
// we may have a sequence number from the previous inactive queue - re-use that so that the
// receiver is getting the sequence numbers it expects (given that the connection must still be active)
// Lasily create send queue // Lasily create send queue
_sendQueue = SendQueue::create(_parentSocket, _destination); _sendQueue = SendQueue::create(_parentSocket, _destination, _inactiveSendQueueSequenceNumber);
#ifdef UDT_CONNECTION_DEBUG #ifdef UDT_CONNECTION_DEBUG
qCDebug(networking) << "Created SendQueue for connection to" << _destination; qCDebug(networking) << "Created SendQueue for connection to" << _destination;
@ -105,6 +109,10 @@ SendQueue& Connection::getSendQueue() {
} }
void Connection::queueInactive() { void Connection::queueInactive() {
// get the current sequence number from the send queue, this is to be re-used if the send
// queue is re-activated for this connection
_inactiveSendQueueSequenceNumber = _sendQueue->getCurrentSequenceNumber();
// tell our current send queue to go down and reset our ptr to it to null // tell our current send queue to go down and reset our ptr to it to null
stopSendQueue(); stopSendQueue();

View file

@ -139,6 +139,8 @@ private:
SequenceNumber _lastSentACK; // The last sent ACK SequenceNumber _lastSentACK; // The last sent ACK
SequenceNumber _lastSentACK2; // The last sent ACK sub-sequence number in an ACK2 SequenceNumber _lastSentACK2; // The last sent ACK sub-sequence number in an ACK2
SequenceNumber _inactiveSendQueueSequenceNumber { 0 };
int _acksDuringSYN { 1 }; // The number of non-SYN ACKs sent during SYN int _acksDuringSYN { 1 }; // The number of non-SYN ACKs sent during SYN
int _lightACKsDuringSYN { 1 }; // The number of lite ACKs sent during SYN interval int _lightACKsDuringSYN { 1 }; // The number of lite ACKs sent during SYN interval

View file

@ -52,11 +52,11 @@ private:
Mutex2& _mutex2; Mutex2& _mutex2;
}; };
std::unique_ptr<SendQueue> SendQueue::create(Socket* socket, HifiSockAddr destination) { std::unique_ptr<SendQueue> SendQueue::create(Socket* socket, HifiSockAddr destination, SequenceNumber currentSequenceNumber) {
Q_ASSERT_X(socket, "SendQueue::create", "Must be called with a valid Socket*"); Q_ASSERT_X(socket, "SendQueue::create", "Must be called with a valid Socket*");
auto queue = std::unique_ptr<SendQueue>(new SendQueue(socket, destination)); auto queue = std::unique_ptr<SendQueue>(new SendQueue(socket, destination, currentSequenceNumber));
// Setup queue private thread // Setup queue private thread
QThread* thread = new QThread; QThread* thread = new QThread;
thread->setObjectName("Networking: SendQueue " + destination.objectName()); // Name thread for easier debug thread->setObjectName("Networking: SendQueue " + destination.objectName()); // Name thread for easier debug
@ -74,10 +74,12 @@ std::unique_ptr<SendQueue> SendQueue::create(Socket* socket, HifiSockAddr destin
return queue; return queue;
} }
SendQueue::SendQueue(Socket* socket, HifiSockAddr dest) : SendQueue::SendQueue(Socket* socket, HifiSockAddr dest, SequenceNumber currentSequenceNumber) :
_socket(socket), _socket(socket),
_destination(dest) _destination(dest),
_currentSequenceNumber(currentSequenceNumber)
{ {
} }
void SendQueue::queuePacket(std::unique_ptr<Packet> packet) { void SendQueue::queuePacket(std::unique_ptr<Packet> packet) {
@ -389,6 +391,7 @@ bool SendQueue::isInactive(bool sentAPacket) {
static const int NUM_TIMEOUTS_BEFORE_INACTIVE = 16; static const int NUM_TIMEOUTS_BEFORE_INACTIVE = 16;
static const int MIN_SECONDS_BEFORE_INACTIVE_MS = 5 * 1000; static const int MIN_SECONDS_BEFORE_INACTIVE_MS = 5 * 1000;
if (_timeoutExpiryCount >= NUM_TIMEOUTS_BEFORE_INACTIVE && if (_timeoutExpiryCount >= NUM_TIMEOUTS_BEFORE_INACTIVE &&
_lastReceiverResponse > 0 &&
(QDateTime::currentMSecsSinceEpoch() - _lastReceiverResponse) > MIN_SECONDS_BEFORE_INACTIVE_MS) { (QDateTime::currentMSecsSinceEpoch() - _lastReceiverResponse) > MIN_SECONDS_BEFORE_INACTIVE_MS) {
// If the flow window has been full for over CONSIDER_INACTIVE_AFTER, // If the flow window has been full for over CONSIDER_INACTIVE_AFTER,
// then signal the queue is inactive and return so it can be cleaned up // then signal the queue is inactive and return so it can be cleaned up

View file

@ -50,7 +50,8 @@ public:
Stopped Stopped
}; };
static std::unique_ptr<SendQueue> create(Socket* socket, HifiSockAddr destination); static std::unique_ptr<SendQueue> create(Socket* socket, HifiSockAddr destination,
SequenceNumber currentSequenceNumber = SequenceNumber());
void queuePacket(std::unique_ptr<Packet> packet); void queuePacket(std::unique_ptr<Packet> packet);
void queuePacketList(std::unique_ptr<PacketList> packetList); void queuePacketList(std::unique_ptr<PacketList> packetList);
@ -83,7 +84,7 @@ private slots:
void run(); void run();
private: private:
SendQueue(Socket* socket, HifiSockAddr dest); SendQueue(Socket* socket, HifiSockAddr dest, SequenceNumber currentSequenceNumber);
SendQueue(SendQueue& other) = delete; SendQueue(SendQueue& other) = delete;
SendQueue(SendQueue&& other) = delete; SendQueue(SendQueue&& other) = delete;
@ -108,7 +109,7 @@ private:
std::atomic<uint32_t> _lastACKSequenceNumber { 0 }; // Last ACKed sequence number std::atomic<uint32_t> _lastACKSequenceNumber { 0 }; // Last ACKed sequence number
SequenceNumber _currentSequenceNumber; // Last sequence number sent out SequenceNumber _currentSequenceNumber { 0 }; // Last sequence number sent out
std::atomic<uint32_t> _atomicCurrentSequenceNumber { 0 }; // Atomic for last sequence number sent out std::atomic<uint32_t> _atomicCurrentSequenceNumber { 0 }; // Atomic for last sequence number sent out
std::atomic<int> _packetSendPeriod { 0 }; // Interval between two packet send event in microseconds, set from CC std::atomic<int> _packetSendPeriod { 0 }; // Interval between two packet send event in microseconds, set from CC