diff --git a/libraries/networking/src/udt/CongestionControl.cpp b/libraries/networking/src/udt/CongestionControl.cpp index e8afdc5fe2..2b71ea5355 100644 --- a/libraries/networking/src/udt/CongestionControl.cpp +++ b/libraries/networking/src/udt/CongestionControl.cpp @@ -62,10 +62,10 @@ void DefaultCC::onACK(SequenceNumber ackNum) { if (_slowStart) { // we are in slow start phase - increase the congestion window size by the number of packets just ACKed - _congestionWindowSize += seqlen(_slowStartLastACK, ackNum); + _congestionWindowSize += seqlen(_lastACK, ackNum); // update the last ACK - _slowStartLastACK = ackNum; + _lastACK = ackNum; // check if we can get out of slow start (is our new congestion window size bigger than the max) if (_congestionWindowSize > _maxCongestionWindowSize) { @@ -186,11 +186,11 @@ void DefaultCC::onTimeout() { stopSlowStart(); } else { // UDT used to do the following on timeout if not in slow start - we should check if it could be helpful - // _lastDecreasePeriod = _packetSendPeriod; - // _packetSendPeriod = ceil(_packetSendPeriod * 2); - + _lastDecreasePeriod = _packetSendPeriod; + _packetSendPeriod = ceil(_packetSendPeriod * 2); + // this seems odd - the last ack they were setting _lastDecreaseMaxSeq to only applies to slow start - // _lastDecreaseMaxSeq = _slowStartLastAck; + _lastDecreaseMaxSeq = _lastACK; } } @@ -209,6 +209,5 @@ void DefaultCC::stopSlowStart() { } void DefaultCC::setInitialSendSequenceNumber(udt::SequenceNumber seqNum) { - _slowStartLastACK = seqNum; - _lastDecreaseMaxSeq = seqNum - 1; + _lastACK = _lastDecreaseMaxSeq = seqNum - 1; } diff --git a/libraries/networking/src/udt/CongestionControl.h b/libraries/networking/src/udt/CongestionControl.h index c2b4227667..3a5c8d0d00 100644 --- a/libraries/networking/src/udt/CongestionControl.h +++ b/libraries/networking/src/udt/CongestionControl.h @@ -41,7 +41,7 @@ public: virtual void init() {} virtual void onACK(SequenceNumber ackNum) {} virtual void onLoss(SequenceNumber rangeStart, SequenceNumber rangeEnd) {} - + virtual void onTimeout() {} protected: void setAckInterval(int ackInterval) { _ackInterval = ackInterval; } void setRTO(int rto) { _userDefinedRTO = true; _rto = rto; } @@ -115,7 +115,7 @@ private: p_high_resolution_clock::time_point _lastRCTime = p_high_resolution_clock::now(); // last rate increase time bool _slowStart { true }; // if in slow start phase - SequenceNumber _slowStartLastACK; // last ACKed seq num from previous slow start check + SequenceNumber _lastACK; // last ACKed sequence number from previous bool _loss { false }; // if loss happened since last rate increase SequenceNumber _lastDecreaseMaxSeq; // max pkt seq num sent out when last decrease happened double _lastDecreasePeriod { 1 }; // value of _packetSendPeriod when last decrease happened diff --git a/libraries/networking/src/udt/Connection.cpp b/libraries/networking/src/udt/Connection.cpp index 96d4b65aec..f75a9535f5 100644 --- a/libraries/networking/src/udt/Connection.cpp +++ b/libraries/networking/src/udt/Connection.cpp @@ -98,6 +98,7 @@ SendQueue& Connection::getSendQueue() { QObject::connect(_sendQueue.get(), &SendQueue::packetSent, this, &Connection::recordSentPackets); QObject::connect(_sendQueue.get(), &SendQueue::packetRetransmitted, this, &Connection::recordRetransmission); QObject::connect(_sendQueue.get(), &SendQueue::queueInactive, this, &Connection::queueInactive); + QObject::connect(_sendQueue.get(), &SendQueue::timeout, this, &Connection::queueTimeout); // set defaults on the send queue from our congestion control object and estimatedTimeout() _sendQueue->setPacketSendPeriod(_congestionControl->_packetSendPeriod); @@ -129,6 +130,12 @@ void Connection::queueInactive() { } } +void Connection::queueTimeout() { + updateCongestionControlAndSendQueue([this]{ + _congestionControl->onTimeout(); + }); +} + void Connection::sendReliablePacket(std::unique_ptr packet) { Q_ASSERT_X(packet->isReliable(), "Connection::send", "Trying to send an unreliable packet reliably."); getSendQueue().queuePacket(std::move(packet)); diff --git a/libraries/networking/src/udt/Connection.h b/libraries/networking/src/udt/Connection.h index bf56a468aa..8d80e736af 100644 --- a/libraries/networking/src/udt/Connection.h +++ b/libraries/networking/src/udt/Connection.h @@ -84,6 +84,7 @@ private slots: void recordSentPackets(int payload, int total); void recordRetransmission(); void queueInactive(); + void queueTimeout(); private: void sendACK(bool wasCausedBySyncTimeout = true); diff --git a/libraries/networking/src/udt/SendQueue.cpp b/libraries/networking/src/udt/SendQueue.cpp index 87f2f0a5bc..9701561ec7 100644 --- a/libraries/networking/src/udt/SendQueue.cpp +++ b/libraries/networking/src/udt/SendQueue.cpp @@ -514,6 +514,11 @@ bool SendQueue::isInactive(bool sentAPacket) { // Note that thanks to the DoubleLock we have the _naksLock right now _naks.append(SequenceNumber(_lastACKSequenceNumber) + 1, _currentSequenceNumber); + + // we have the lock again - time to unlock it + locker.unlock(); + + emit timeout(); } } } diff --git a/libraries/networking/src/udt/SendQueue.h b/libraries/networking/src/udt/SendQueue.h index 0f646c3d9c..9400ae8352 100644 --- a/libraries/networking/src/udt/SendQueue.h +++ b/libraries/networking/src/udt/SendQueue.h @@ -78,6 +78,8 @@ signals: void packetRetransmitted(); void queueInactive(); + + void timeout(); private slots: void run();