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