Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(486)

Side by Side Diff: net/quic/quic_packet_generator.cc

Issue 12334063: Land recent QUIC changes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: more EXPECT_FALSE Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/quic/quic_packet_generator.h ('k') | net/quic/quic_packet_generator_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012 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_packet_generator.h"
6
7 #include "base/logging.h"
8 #include "net/quic/quic_fec_group.h"
9 #include "net/quic/quic_utils.h"
10
11 using base::StringPiece;
12
13 namespace net {
14
15 QuicPacketGenerator::QuicPacketGenerator(DelegateInterface* delegate,
16 QuicPacketCreator* creator)
17 : delegate_(delegate),
18 packet_creator_(creator),
19 should_flush_(true),
20 should_send_ack_(false),
21 should_send_feedback_(false) {
22 }
23
24 QuicPacketGenerator::~QuicPacketGenerator() {
25 for (QuicFrames::iterator it = queued_control_frames_.begin();
26 it != queued_control_frames_.end(); ++it) {
27 switch (it->type) {
28 case PADDING_FRAME:
29 delete it->padding_frame;
30 break;
31 case STREAM_FRAME:
32 delete it->stream_frame;
33 break;
34 case ACK_FRAME:
35 delete it->ack_frame;
36 break;
37 case CONGESTION_FEEDBACK_FRAME:
38 delete it->congestion_feedback_frame;
39 break;
40 case RST_STREAM_FRAME:
41 delete it->rst_stream_frame;
42 break;
43 case CONNECTION_CLOSE_FRAME:
44 delete it->connection_close_frame;
45 break;
46 case GOAWAY_FRAME:
47 delete it->goaway_frame;
48 break;
49 case NUM_FRAME_TYPES:
50 DCHECK(false) << "Cannot delete type: " << it->type;
51 }
52 }
53 }
54
55 void QuicPacketGenerator::SetShouldSendAck(bool also_send_feedback) {
56 should_send_ack_ = true;
57 should_send_feedback_ = also_send_feedback;
58 SendQueuedData();
59 }
60
61
62 void QuicPacketGenerator::AddControlFrame(const QuicFrame& frame) {
63 queued_control_frames_.push_back(frame);
64 SendQueuedData();
65 }
66
67 QuicConsumedData QuicPacketGenerator::ConsumeData(QuicStreamId id,
68 StringPiece data,
69 QuicStreamOffset offset,
70 bool fin) {
71 SendQueuedData();
72
73 size_t total_bytes_consumed = 0;
74 bool fin_consumed = false;
75
76 // Make sure any queued data gets sent before new data.
77 // SendQueuedData();
78
79 while (delegate_->CanWrite(false)) {
80 // TODO(rch) figure out FEC.
81 // packet_creator_.MaybeStartFEC();
82 QuicFrame frame;
83 size_t bytes_consumed = packet_creator_->CreateStreamFrame(
84 id, data, offset + total_bytes_consumed, fin, &frame);
85 bool success = packet_creator_->AddSavedFrame(frame);
86 DCHECK(success);
87
88 total_bytes_consumed += bytes_consumed;
89 fin_consumed = fin && bytes_consumed == data.size();
90 data.remove_prefix(bytes_consumed);
91 DCHECK(data.empty() || packet_creator_->BytesFree() == 0u);
92
93 // TODO(ianswett): Restore packet reordering.
94 if (should_flush_ || !packet_creator_->HasRoomForStreamFrame()) {
95 SerializeAndSendPacket();
96 }
97
98 if (data.empty()) {
99 // We're done writing the data. Exit the loop.
100 // We don't make this a precondition because we could have 0 bytes of data
101 // if we're simply writing a fin.
102 break;
103 }
104 }
105
106 // Ensure the FEC group is closed at the end of this method unless other
107 // writes are pending.
108 if (should_flush_ && packet_creator_->ShouldSendFec(true)) {
109 SerializedPacket serialized_fec = packet_creator_->SerializeFec();
110 DCHECK(serialized_fec.packet);
111 delegate_->OnSerializedPacket(serialized_fec);
112 }
113
114 DCHECK(!should_flush_ || !packet_creator_->HasPendingFrames());
115 return QuicConsumedData(total_bytes_consumed, fin_consumed);
116 }
117
118 void QuicPacketGenerator::SendQueuedData() {
119 while (HasPendingData() && delegate_->CanWrite(false)) {
120 if (!AddNextPendingFrame()) {
121 // Packet was full, so serialize and send it.
122 SerializeAndSendPacket();
123 }
124 }
125
126 if (should_flush_) {
127 if (packet_creator_->HasPendingFrames()) {
128 SerializeAndSendPacket();
129 }
130
131 // Ensure the FEC group is closed at the end of this method unless other
132 // writes are pending.
133 if (packet_creator_->ShouldSendFec(true)) {
134 SerializedPacket serialized_fec = packet_creator_->SerializeFec();
135 DCHECK(serialized_fec.packet);
136 delegate_->OnSerializedPacket(serialized_fec);
137 }
138 }
139 }
140
141 void QuicPacketGenerator::StartBatchOperations() {
142 should_flush_ = false;
143 }
144
145 void QuicPacketGenerator::FinishBatchOperations() {
146 should_flush_ = true;
147 SendQueuedData();
148 }
149
150 bool QuicPacketGenerator::HasQueuedData() const {
151 return packet_creator_->HasPendingFrames() || HasPendingData();
152 }
153
154 bool QuicPacketGenerator::HasPendingData() const {
155 return should_send_ack_ || should_send_feedback_ ||
156 !queued_control_frames_.empty();
157 }
158
159 bool QuicPacketGenerator::AddNextPendingFrame() {
160 if (should_send_ack_) {
161 pending_ack_frame_.reset(delegate_->CreateAckFrame());
162 if (!packet_creator_->AddSavedFrame(QuicFrame(pending_ack_frame_.get()))) {
163 // packet was full
164 return false;
165 }
166 should_send_ack_ = false;
167 return true;
168 }
169
170 if (should_send_feedback_) {
171 pending_feedback_frame_.reset(delegate_->CreateFeedbackFrame());
172 if (!packet_creator_->AddSavedFrame(QuicFrame(
173 pending_feedback_frame_.get()))) {
174 // packet was full
175 return false;
176 }
177 should_send_feedback_ = false;
178 return true;
179 }
180
181 DCHECK(!queued_control_frames_.empty());
182 if (!packet_creator_->AddSavedFrame(queued_control_frames_.back())) {
183 // packet was full
184 return false;
185 }
186 queued_control_frames_.pop_back();
187 return true;
188 }
189
190 void QuicPacketGenerator::SerializeAndSendPacket() {
191 packet_creator_->MaybeStartFEC();
192 SerializedPacket serialized_packet = packet_creator_->SerializePacket();
193 DCHECK(serialized_packet.packet);
194 delegate_->OnSerializedPacket(serialized_packet);
195
196 if (packet_creator_->ShouldSendFec(false)) {
197 SerializedPacket serialized_fec = packet_creator_->SerializeFec();
198 DCHECK(serialized_fec.packet);
199 delegate_->OnSerializedPacket(serialized_fec);
200 }
201 }
202
203 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/quic_packet_generator.h ('k') | net/quic/quic_packet_generator_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698