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 3// found in the LICENSE file. 4 5#include "net/quic/quic_ack_notifier_manager.h" 6 7#include <stddef.h> 8#include <list> 9#include <map> 10#include <utility> 11#include <vector> 12 13#include "base/stl_util.h" 14#include "net/quic/quic_ack_notifier.h" 15#include "net/quic/quic_protocol.h" 16 17namespace net { 18 19AckNotifierManager::AckNotifierManager() {} 20 21AckNotifierManager::~AckNotifierManager() { 22 STLDeleteElements(&ack_notifiers_); 23} 24 25void AckNotifierManager::OnPacketAcked( 26 QuicPacketSequenceNumber sequence_number, 27 QuicTime::Delta delta_largest_observed) { 28 // Inform all the registered AckNotifiers of the new ACK. 29 AckNotifierMap::iterator map_it = ack_notifier_map_.find(sequence_number); 30 if (map_it == ack_notifier_map_.end()) { 31 // No AckNotifier is interested in this sequence number. 32 return; 33 } 34 35 // One or more AckNotifiers are registered as interested in this sequence 36 // number. Iterate through them and call OnAck on each. 37 for (AckNotifierSet::iterator set_it = map_it->second.begin(); 38 set_it != map_it->second.end(); ++set_it) { 39 QuicAckNotifier* ack_notifier = *set_it; 40 ack_notifier->OnAck(sequence_number, delta_largest_observed); 41 42 // If this has resulted in an empty AckNotifer, erase it. 43 if (ack_notifier->IsEmpty()) { 44 delete ack_notifier; 45 ack_notifiers_.erase(ack_notifier); 46 } 47 } 48 49 // Remove the sequence number from the map as we have notified all the 50 // registered AckNotifiers, and we won't see it again. 51 ack_notifier_map_.erase(map_it); 52} 53 54void AckNotifierManager::UpdateSequenceNumber( 55 QuicPacketSequenceNumber old_sequence_number, 56 QuicPacketSequenceNumber new_sequence_number) { 57 AckNotifierMap::iterator map_it = ack_notifier_map_.find(old_sequence_number); 58 if (map_it != ack_notifier_map_.end()) { 59 // We will add an entry to the map for the new sequence number, and move 60 // the 61 // list of AckNotifiers over. 62 AckNotifierSet new_set; 63 for (AckNotifierSet::iterator notifier_it = map_it->second.begin(); 64 notifier_it != map_it->second.end(); ++notifier_it) { 65 (*notifier_it) 66 ->UpdateSequenceNumber(old_sequence_number, new_sequence_number); 67 new_set.insert(*notifier_it); 68 } 69 ack_notifier_map_[new_sequence_number] = new_set; 70 ack_notifier_map_.erase(map_it); 71 } 72} 73 74void AckNotifierManager::OnSerializedPacket( 75 const SerializedPacket& serialized_packet) { 76 // Run through all the frames and if any of them are stream frames and have 77 // an AckNotifier registered, then inform the AckNotifier that it should be 78 // interested in this packet's sequence number. 79 80 RetransmittableFrames* frames = serialized_packet.retransmittable_frames; 81 82 // AckNotifiers can only be attached to retransmittable frames. 83 if (!frames) { 84 return; 85 } 86 87 for (QuicFrames::const_iterator it = frames->frames().begin(); 88 it != frames->frames().end(); ++it) { 89 if (it->type == STREAM_FRAME && it->stream_frame->notifier != NULL) { 90 QuicAckNotifier* notifier = it->stream_frame->notifier; 91 92 // The AckNotifier needs to know it is tracking this packet's sequence 93 // number. 94 notifier->AddSequenceNumber(serialized_packet.sequence_number, 95 serialized_packet.packet->length()); 96 97 // Update the mapping in the other direction, from sequence 98 // number to AckNotifier. 99 ack_notifier_map_[serialized_packet.sequence_number].insert(notifier); 100 101 // Take ownership of the AckNotifier. 102 ack_notifiers_.insert(notifier); 103 } 104 } 105} 106 107} // namespace net 108