| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/quic/quic_sent_packet_manager.h" | 5 #include "net/quic/quic_sent_packet_manager.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/stl_util.h" | 8 #include "base/stl_util.h" |
| 9 #include "net/quic/congestion_control/pacing_sender.h" | 9 #include "net/quic/congestion_control/pacing_sender.h" |
| 10 #include "net/quic/quic_ack_notifier_manager.h" | 10 #include "net/quic/quic_ack_notifier_manager.h" |
| 11 | 11 |
| 12 using std::make_pair; | 12 using std::make_pair; |
| 13 using std::max; | 13 using std::max; |
| 14 using std::min; | 14 using std::min; |
| 15 | 15 |
| 16 // TODO(rtenneti): Remove this. | 16 // TODO(rtenneti): Remove this. |
| 17 // Do not flip this flag until the flakiness of the | 17 // Do not flip this flag until the flakiness of the |
| 18 // net/tools/quic/end_to_end_test is fixed. | 18 // net/tools/quic/end_to_end_test is fixed. |
| 19 // If true, then QUIC connections will track the retransmission history of a | 19 // If true, then QUIC connections will track the retransmission history of a |
| 20 // packet so that an ack of a previous transmission will ack the data of all | 20 // packet so that an ack of a previous transmission will ack the data of all |
| 21 // other transmissions. | 21 // other transmissions. |
| 22 bool FLAGS_track_retransmission_history = false; | 22 bool FLAGS_track_retransmission_history = false; |
| 23 | 23 |
| 24 // A test-only flag to prevent the RTO from backing off when multiple sequential | |
| 25 // tail drops occur. | |
| 26 bool FLAGS_limit_rto_increase_for_tests = false; | |
| 27 | |
| 28 // Do not remove this flag until the Finch-trials described in b/11706275 | 24 // Do not remove this flag until the Finch-trials described in b/11706275 |
| 29 // are complete. | 25 // are complete. |
| 30 // If true, QUIC connections will support the use of a pacing algorithm when | 26 // If true, QUIC connections will support the use of a pacing algorithm when |
| 31 // sending packets, in an attempt to reduce packet loss. The client must also | 27 // sending packets, in an attempt to reduce packet loss. The client must also |
| 32 // request pacing for the server to enable it. | 28 // request pacing for the server to enable it. |
| 33 bool FLAGS_enable_quic_pacing = false; | 29 bool FLAGS_enable_quic_pacing = false; |
| 34 | 30 |
| 35 namespace net { | 31 namespace net { |
| 36 namespace { | 32 namespace { |
| 37 static const int kBitrateSmoothingPeriodMs = 1000; | 33 static const int kBitrateSmoothingPeriodMs = 1000; |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 252 void QuicSentPacketManager::ClearPreviousRetransmissions(size_t num_to_clear) { | 248 void QuicSentPacketManager::ClearPreviousRetransmissions(size_t num_to_clear) { |
| 253 UnackedPacketMap::iterator it = unacked_packets_.begin(); | 249 UnackedPacketMap::iterator it = unacked_packets_.begin(); |
| 254 while (it != unacked_packets_.end() && num_to_clear > 0) { | 250 while (it != unacked_packets_.end() && num_to_clear > 0) { |
| 255 QuicPacketSequenceNumber sequence_number = it->first; | 251 QuicPacketSequenceNumber sequence_number = it->first; |
| 256 // If this is not a previous transmission then there is no point | 252 // If this is not a previous transmission then there is no point |
| 257 // in clearing out any further packets, because it will not affect | 253 // in clearing out any further packets, because it will not affect |
| 258 // the high water mark. | 254 // the high water mark. |
| 259 SequenceNumberSet* previous_transmissions = | 255 SequenceNumberSet* previous_transmissions = |
| 260 it->second.previous_transmissions; | 256 it->second.previous_transmissions; |
| 261 if (previous_transmissions == NULL) { | 257 if (previous_transmissions == NULL) { |
| 258 if (it->second.retransmittable_frames == NULL) { |
| 259 // This is a current transmission, but a previous transmission has |
| 260 // been acked, so it's safe to remove. |
| 261 it = MarkPacketHandled(sequence_number, NOT_RECEIVED_BY_PEER); |
| 262 --num_to_clear; |
| 263 continue; |
| 264 } |
| 262 break; | 265 break; |
| 263 } | 266 } |
| 264 QuicPacketSequenceNumber newest_transmission = | 267 QuicPacketSequenceNumber newest_transmission = |
| 265 *previous_transmissions->rbegin(); | 268 *previous_transmissions->rbegin(); |
| 266 if (sequence_number == newest_transmission) { | 269 if (sequence_number == newest_transmission) { |
| 267 break; | 270 break; |
| 268 } | 271 } |
| 269 | 272 |
| 270 DCHECK(it->second.retransmittable_frames == NULL); | 273 DCHECK(it->second.retransmittable_frames == NULL); |
| 271 previous_transmissions->erase(sequence_number); | 274 previous_transmissions->erase(sequence_number); |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 415 unacked_packets_.find(newest_transmission); | 418 unacked_packets_.find(newest_transmission); |
| 416 if (HasCryptoHandshake(newest_it->second)) { | 419 if (HasCryptoHandshake(newest_it->second)) { |
| 417 --pending_crypto_packet_count_; | 420 --pending_crypto_packet_count_; |
| 418 } | 421 } |
| 419 // If we have received an ack for a previous transmission of a packet, | 422 // If we have received an ack for a previous transmission of a packet, |
| 420 // we want to keep the "new" transmission of the packet unacked, | 423 // we want to keep the "new" transmission of the packet unacked, |
| 421 // but prevent the data from being retransmitted. | 424 // but prevent the data from being retransmitted. |
| 422 delete newest_it->second.retransmittable_frames; | 425 delete newest_it->second.retransmittable_frames; |
| 423 newest_it->second.retransmittable_frames = NULL; | 426 newest_it->second.retransmittable_frames = NULL; |
| 424 newest_it->second.previous_transmissions = NULL; | 427 newest_it->second.previous_transmissions = NULL; |
| 425 pending_retransmissions_.erase(newest_transmission); | |
| 426 } | 428 } |
| 427 | 429 |
| 428 // Clear out information all previous transmissions. | 430 // Clear out information all previous transmissions. |
| 429 ++previous_transmissions_it; | 431 ++previous_transmissions_it; |
| 430 while (previous_transmissions_it != previous_transmissions->rend()) { | 432 while (previous_transmissions_it != previous_transmissions->rend()) { |
| 431 QuicPacketSequenceNumber previous_transmission = *previous_transmissions_it; | 433 QuicPacketSequenceNumber previous_transmission = *previous_transmissions_it; |
| 432 ++previous_transmissions_it; | 434 ++previous_transmissions_it; |
| 433 // If the packet was TLP retransmitted, the old copy was not yet considered | 435 // If the packet was TLP retransmitted, the old copy was not yet considered |
| 434 // lost or abandoned, so do that now. | 436 // lost or abandoned, so do that now. |
| 435 if (ContainsKey(pending_packets_, previous_transmission)) { | 437 if (ContainsKey(pending_packets_, previous_transmission)) { |
| 436 send_algorithm_->OnPacketLost(previous_transmission, clock_->Now()); | 438 send_algorithm_->OnPacketLost(previous_transmission, clock_->Now()); |
| 437 OnPacketAbandoned(previous_transmission); | 439 OnPacketAbandoned(previous_transmission); |
| 438 } | 440 } |
| 439 DiscardPacket(previous_transmission); | 441 DiscardPacket(previous_transmission); |
| 440 } | 442 } |
| 441 | 443 |
| 442 delete previous_transmissions; | 444 delete previous_transmissions; |
| 443 | 445 |
| 446 if (ContainsKey(pending_retransmissions_, newest_transmission)) { |
| 447 pending_retransmissions_.erase(newest_transmission); |
| 448 if (!ContainsKey(pending_packets_, newest_transmission)) { |
| 449 // If the newest transmission has already been marked for retransmission |
| 450 // and has already been abandoned, then we should remove it from |
| 451 // unacked_packets_, as well as cancel the retransmission. |
| 452 DCHECK(ContainsKey(unacked_packets_, newest_transmission)); |
| 453 DCHECK(!unacked_packets_[newest_transmission].previous_transmissions); |
| 454 unacked_packets_.erase(newest_transmission); |
| 455 } |
| 456 } |
| 457 |
| 444 UnackedPacketMap::iterator next_unacked = unacked_packets_.begin(); | 458 UnackedPacketMap::iterator next_unacked = unacked_packets_.begin(); |
| 445 while (next_unacked != unacked_packets_.end() && | 459 while (next_unacked != unacked_packets_.end() && |
| 446 next_unacked->first < sequence_number) { | 460 next_unacked->first < sequence_number) { |
| 447 ++next_unacked; | 461 ++next_unacked; |
| 448 } | 462 } |
| 449 return next_unacked; | 463 return next_unacked; |
| 450 } | 464 } |
| 451 | 465 |
| 452 void QuicSentPacketManager::DiscardPacket( | 466 void QuicSentPacketManager::DiscardPacket( |
| 453 QuicPacketSequenceNumber sequence_number) { | 467 QuicPacketSequenceNumber sequence_number) { |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 619 MarkForRetransmission(sequence_number, TLP_RETRANSMISSION); | 633 MarkForRetransmission(sequence_number, TLP_RETRANSMISSION); |
| 620 return; | 634 return; |
| 621 } | 635 } |
| 622 DLOG(FATAL) | 636 DLOG(FATAL) |
| 623 << "No retransmittable packets, so RetransmitOldestPacket failed."; | 637 << "No retransmittable packets, so RetransmitOldestPacket failed."; |
| 624 } | 638 } |
| 625 | 639 |
| 626 void QuicSentPacketManager::RetransmitAllPackets() { | 640 void QuicSentPacketManager::RetransmitAllPackets() { |
| 627 // Abandon all retransmittable packets and packets older than the | 641 // Abandon all retransmittable packets and packets older than the |
| 628 // retransmission delay. | 642 // retransmission delay. |
| 629 QuicTime::Delta retransmission_delay = GetRetransmissionDelay(); | |
| 630 QuicTime max_send_time = | |
| 631 clock_->ApproximateNow().Subtract(retransmission_delay); | |
| 632 | 643 |
| 633 DVLOG(1) << "OnRetransmissionTimeout() fired with " | 644 DVLOG(1) << "OnRetransmissionTimeout() fired with " |
| 634 << unacked_packets_.size() << " unacked packets."; | 645 << unacked_packets_.size() << " unacked packets."; |
| 635 | 646 |
| 636 // Request retransmission of all retransmittable packets when the RTO | 647 // Request retransmission of all retransmittable packets when the RTO |
| 637 // fires, and let the congestion manager decide how many to send | 648 // fires, and let the congestion manager decide how many to send |
| 638 // immediately and the remaining packets will be queued. | 649 // immediately and the remaining packets will be queued. |
| 639 // Abandon any non-retransmittable packets that are sufficiently old. | 650 // Abandon any non-retransmittable packets that are sufficiently old. |
| 640 bool packets_retransmitted = false; | 651 bool packets_retransmitted = false; |
| 641 for (UnackedPacketMap::const_iterator it = unacked_packets_.begin(); | 652 for (UnackedPacketMap::const_iterator it = unacked_packets_.begin(); |
| 642 it != unacked_packets_.end(); ++it) { | 653 it != unacked_packets_.end(); ++it) { |
| 643 if (it->second.retransmittable_frames != NULL) { | 654 if (it->second.retransmittable_frames != NULL) { |
| 644 OnPacketAbandoned(it->first); | |
| 645 packets_retransmitted = true; | 655 packets_retransmitted = true; |
| 646 MarkForRetransmission(it->first, RTO_RETRANSMISSION); | 656 MarkForRetransmission(it->first, RTO_RETRANSMISSION); |
| 647 } else if (it->second.sent_time <= max_send_time) { | |
| 648 OnPacketAbandoned(it->first); | |
| 649 } | 657 } |
| 650 } | 658 } |
| 651 | 659 |
| 652 // Only inform the send algorithm of an RTO if data was retransmitted. | 660 pending_packets_.clear(); |
| 661 send_algorithm_->OnRetransmissionTimeout(packets_retransmitted); |
| 653 if (packets_retransmitted) { | 662 if (packets_retransmitted) { |
| 654 ++consecutive_rto_count_; | 663 ++consecutive_rto_count_; |
| 655 send_algorithm_->OnRetransmissionTimeout(); | |
| 656 } | 664 } |
| 657 } | 665 } |
| 658 | 666 |
| 659 QuicSentPacketManager::RetransmissionTimeoutMode | 667 QuicSentPacketManager::RetransmissionTimeoutMode |
| 660 QuicSentPacketManager::GetRetransmissionMode() const { | 668 QuicSentPacketManager::GetRetransmissionMode() const { |
| 661 DCHECK(!pending_packets_.empty()); | 669 DCHECK(!pending_packets_.empty()); |
| 662 if (pending_crypto_packet_count_ > 0) { | 670 if (pending_crypto_packet_count_ > 0) { |
| 663 return HANDSHAKE_MODE; | 671 return HANDSHAKE_MODE; |
| 664 } | 672 } |
| 665 if (consecutive_tlp_count_ < max_tail_loss_probes_) { | 673 if (consecutive_tlp_count_ < max_tail_loss_probes_) { |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 743 // If the number of retransmissions has maxed out, don't lose or retransmit | 751 // If the number of retransmissions has maxed out, don't lose or retransmit |
| 744 // any more packets. | 752 // any more packets. |
| 745 if (num_retransmitted >= kMaxRetransmissionsPerAck) { | 753 if (num_retransmitted >= kMaxRetransmissionsPerAck) { |
| 746 ++it; | 754 ++it; |
| 747 continue; | 755 continue; |
| 748 } | 756 } |
| 749 | 757 |
| 750 lost_packets.insert(sequence_number); | 758 lost_packets.insert(sequence_number); |
| 751 if (transmission_info.retransmittable_frames) { | 759 if (transmission_info.retransmittable_frames) { |
| 752 ++num_retransmitted; | 760 ++num_retransmitted; |
| 753 MarkForRetransmission(*it, NACK_RETRANSMISSION); | 761 MarkForRetransmission(sequence_number, NACK_RETRANSMISSION); |
| 762 } else { |
| 763 // Since we will not retransmit this, we need to remove it from |
| 764 // unacked_packets_. This is either the current transmission of |
| 765 // a packet whose previous transmission has been acked, or it |
| 766 // is a packet that has been TLP retransmitted. |
| 767 RemovePreviousTransmission(sequence_number); |
| 768 unacked_packets_.erase(sequence_number); |
| 754 } | 769 } |
| 755 | 770 |
| 756 ++it; | 771 ++it; |
| 757 } | 772 } |
| 758 // Abandon packets after the loop over pending packets, because otherwise it | 773 // Abandon packets after the loop over pending packets, because otherwise it |
| 759 // changes the early retransmit logic and iteration. | 774 // changes the early retransmit logic and iteration. |
| 760 for (SequenceNumberSet::const_iterator it = lost_packets.begin(); | 775 for (SequenceNumberSet::const_iterator it = lost_packets.begin(); |
| 761 it != lost_packets.end(); ++it) { | 776 it != lost_packets.end(); ++it) { |
| 762 // TODO(ianswett): OnPacketLost is also called from TCPCubicSender when | 777 // TODO(ianswett): OnPacketLost is also called from TCPCubicSender when |
| 763 // an FEC packet is lost, but FEC loss information should be shared among | 778 // an FEC packet is lost, but FEC loss information should be shared among |
| 764 // congestion managers. Additionally, if it's expected the FEC packet may | 779 // congestion managers. Additionally, if it's expected the FEC packet may |
| 765 // repair the loss, it should be recorded as a loss to the congestion | 780 // repair the loss, it should be recorded as a loss to the congestion |
| 766 // manager, but not retransmitted until it's known whether the FEC packet | 781 // manager, but not retransmitted until it's known whether the FEC packet |
| 767 // arrived. | 782 // arrived. |
| 768 send_algorithm_->OnPacketLost(*it, ack_receive_time); | 783 QuicPacketSequenceNumber lost_packet = *it; |
| 769 OnPacketAbandoned(*it); | 784 send_algorithm_->OnPacketLost(lost_packet, ack_receive_time); |
| 785 OnPacketAbandoned(lost_packet); |
| 770 } | 786 } |
| 771 } | 787 } |
| 772 | 788 |
| 773 void QuicSentPacketManager::MaybeUpdateRTT( | 789 void QuicSentPacketManager::MaybeUpdateRTT( |
| 774 const ReceivedPacketInfo& received_info, | 790 const ReceivedPacketInfo& received_info, |
| 775 const QuicTime& ack_receive_time) { | 791 const QuicTime& ack_receive_time) { |
| 776 // We calculate the RTT based on the highest ACKed sequence number, the lower | 792 // We calculate the RTT based on the highest ACKed sequence number, the lower |
| 777 // sequence numbers will include the ACK aggregation delay. | 793 // sequence numbers will include the ACK aggregation delay. |
| 778 SendAlgorithmInterface::SentPacketsMap::iterator history_it = | 794 SendAlgorithmInterface::SentPacketsMap::iterator history_it = |
| 779 packet_history_map_.find(received_info.largest_observed); | 795 packet_history_map_.find(received_info.largest_observed); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 850 QuicTime rto_timeout = sent_time.Add(GetRetransmissionDelay()); | 866 QuicTime rto_timeout = sent_time.Add(GetRetransmissionDelay()); |
| 851 | 867 |
| 852 return QuicTime::Max(min_timeout, rto_timeout); | 868 return QuicTime::Max(min_timeout, rto_timeout); |
| 853 } | 869 } |
| 854 default: | 870 default: |
| 855 DCHECK(false); | 871 DCHECK(false); |
| 856 } | 872 } |
| 857 return QuicTime::Zero(); | 873 return QuicTime::Zero(); |
| 858 } | 874 } |
| 859 | 875 |
| 860 const QuicTime::Delta | 876 const QuicTime::Delta QuicSentPacketManager::GetCryptoRetransmissionDelay() |
| 861 QuicSentPacketManager::GetCryptoRetransmissionDelay() const { | 877 const { |
| 862 // This is equivalent to the TailLossProbeDelay, but slightly more aggressive | 878 // This is equivalent to the TailLossProbeDelay, but slightly more aggressive |
| 863 // because crypto handshake messages don't incur a delayed ack time. | 879 // because crypto handshake messages don't incur a delayed ack time. |
| 864 int64 delay_ms = max<int64>(kMinHandshakeTimeoutMs, | 880 int64 delay_ms = max<int64>(kMinHandshakeTimeoutMs, |
| 865 1.5 * SmoothedRtt().ToMilliseconds()); | 881 1.5 * SmoothedRtt().ToMilliseconds()); |
| 866 return QuicTime::Delta::FromMilliseconds( | 882 return QuicTime::Delta::FromMilliseconds( |
| 867 delay_ms << consecutive_crypto_retransmission_count_); | 883 delay_ms << consecutive_crypto_retransmission_count_); |
| 868 } | 884 } |
| 869 | 885 |
| 870 const QuicTime::Delta QuicSentPacketManager::GetTailLossProbeDelay() const { | 886 const QuicTime::Delta QuicSentPacketManager::GetTailLossProbeDelay() const { |
| 871 QuicTime::Delta srtt = SmoothedRtt(); | 887 QuicTime::Delta srtt = SmoothedRtt(); |
| 872 if (pending_packets_.size() == 1) { | 888 if (pending_packets_.size() == 1) { |
| 873 return QuicTime::Delta::Max( | 889 return QuicTime::Delta::Max( |
| 874 srtt.Multiply(1.5).Add(DelayedAckTime()), srtt.Multiply(2)); | 890 srtt.Multiply(1.5).Add(DelayedAckTime()), srtt.Multiply(2)); |
| 875 } | 891 } |
| 876 return QuicTime::Delta::FromMilliseconds( | 892 return QuicTime::Delta::FromMilliseconds( |
| 877 max(kMinTailLossProbeTimeoutMs, | 893 max(kMinTailLossProbeTimeoutMs, |
| 878 static_cast<int64>(2 * srtt.ToMilliseconds()))); | 894 static_cast<int64>(2 * srtt.ToMilliseconds()))); |
| 879 } | 895 } |
| 880 | 896 |
| 881 const QuicTime::Delta QuicSentPacketManager::GetRetransmissionDelay() const { | 897 const QuicTime::Delta QuicSentPacketManager::GetRetransmissionDelay() const { |
| 882 size_t number_retransmissions = consecutive_rto_count_; | |
| 883 // TODO(ianswett): Remove this flag now that EndToEndTest is no longer flaky. | |
| 884 if (FLAGS_limit_rto_increase_for_tests) { | |
| 885 const size_t kTailDropWindowSize = 5; | |
| 886 const size_t kTailDropMaxRetransmissions = 4; | |
| 887 if (pending_packets_.size() <= kTailDropWindowSize) { | |
| 888 // Avoid exponential backoff of RTO when there are only a few packets | |
| 889 // outstanding. This helps avoid the situation where fake packet loss | |
| 890 // causes a packet and it's retransmission to be dropped causing | |
| 891 // test timouts. | |
| 892 if (number_retransmissions <= kTailDropMaxRetransmissions) { | |
| 893 number_retransmissions = 0; | |
| 894 } else { | |
| 895 number_retransmissions -= kTailDropMaxRetransmissions; | |
| 896 } | |
| 897 } | |
| 898 } | |
| 899 | |
| 900 QuicTime::Delta retransmission_delay = send_algorithm_->RetransmissionDelay(); | 898 QuicTime::Delta retransmission_delay = send_algorithm_->RetransmissionDelay(); |
| 901 if (retransmission_delay.IsZero()) { | 899 if (retransmission_delay.IsZero()) { |
| 902 // We are in the initial state, use default timeout values. | 900 // We are in the initial state, use default timeout values. |
| 903 retransmission_delay = | 901 retransmission_delay = |
| 904 QuicTime::Delta::FromMilliseconds(kDefaultRetransmissionTimeMs); | 902 QuicTime::Delta::FromMilliseconds(kDefaultRetransmissionTimeMs); |
| 905 } | 903 } |
| 906 // Calculate exponential back off. | 904 // Calculate exponential back off. |
| 907 retransmission_delay = retransmission_delay.Multiply( | 905 retransmission_delay = retransmission_delay.Multiply( |
| 908 1 << min<size_t>(number_retransmissions, kMaxRetransmissions)); | 906 1 << min<size_t>(consecutive_rto_count_, kMaxRetransmissions)); |
| 909 | 907 |
| 910 // TODO(rch): This code should move to |send_algorithm_|. | 908 // TODO(rch): This code should move to |send_algorithm_|. |
| 911 if (retransmission_delay.ToMilliseconds() < kMinRetransmissionTimeMs) { | 909 if (retransmission_delay.ToMilliseconds() < kMinRetransmissionTimeMs) { |
| 912 return QuicTime::Delta::FromMilliseconds(kMinRetransmissionTimeMs); | 910 return QuicTime::Delta::FromMilliseconds(kMinRetransmissionTimeMs); |
| 913 } | 911 } |
| 914 if (retransmission_delay.ToMilliseconds() > kMaxRetransmissionTimeMs) { | 912 if (retransmission_delay.ToMilliseconds() > kMaxRetransmissionTimeMs) { |
| 915 return QuicTime::Delta::FromMilliseconds(kMaxRetransmissionTimeMs); | 913 return QuicTime::Delta::FromMilliseconds(kMaxRetransmissionTimeMs); |
| 916 } | 914 } |
| 917 return retransmission_delay; | 915 return retransmission_delay; |
| 918 } | 916 } |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 958 if (using_pacing_) { | 956 if (using_pacing_) { |
| 959 return; | 957 return; |
| 960 } | 958 } |
| 961 | 959 |
| 962 using_pacing_ = true; | 960 using_pacing_ = true; |
| 963 send_algorithm_.reset( | 961 send_algorithm_.reset( |
| 964 new PacingSender(send_algorithm_.release(), | 962 new PacingSender(send_algorithm_.release(), |
| 965 QuicTime::Delta::FromMicroseconds(1))); | 963 QuicTime::Delta::FromMicroseconds(1))); |
| 966 } | 964 } |
| 967 | 965 |
| 966 void QuicSentPacketManager::RemovePreviousTransmission( |
| 967 QuicPacketSequenceNumber sequence_number) { |
| 968 SequenceNumberSet* previous_transmissions = |
| 969 unacked_packets_[sequence_number].previous_transmissions; |
| 970 if (!previous_transmissions) { |
| 971 return; |
| 972 } |
| 973 previous_transmissions->erase(sequence_number); |
| 974 if (previous_transmissions->size() == 1) { |
| 975 QuicPacketSequenceNumber current = *previous_transmissions->begin(); |
| 976 unacked_packets_[current].previous_transmissions = NULL; |
| 977 delete previous_transmissions; |
| 978 } |
| 979 } |
| 980 |
| 968 } // namespace net | 981 } // namespace net |
| OLD | NEW |