| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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_packet_generator.h" | 5 #include "net/quic/quic_packet_generator.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "net/quic/quic_fec_group.h" | 8 #include "net/quic/quic_fec_group.h" |
| 9 #include "net/quic/quic_utils.h" | 9 #include "net/quic/quic_utils.h" |
| 10 | 10 |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 105 if (should_flush_ && packet_creator_->ShouldSendFec(true)) { | 105 if (should_flush_ && packet_creator_->ShouldSendFec(true)) { |
| 106 SerializedPacket serialized_fec = packet_creator_->SerializeFec(); | 106 SerializedPacket serialized_fec = packet_creator_->SerializeFec(); |
| 107 DCHECK(serialized_fec.packet); | 107 DCHECK(serialized_fec.packet); |
| 108 delegate_->OnSerializedPacket(serialized_fec); | 108 delegate_->OnSerializedPacket(serialized_fec); |
| 109 } | 109 } |
| 110 | 110 |
| 111 DCHECK(!should_flush_ || !packet_creator_->HasPendingFrames()); | 111 DCHECK(!should_flush_ || !packet_creator_->HasPendingFrames()); |
| 112 return QuicConsumedData(total_bytes_consumed, fin_consumed); | 112 return QuicConsumedData(total_bytes_consumed, fin_consumed); |
| 113 } | 113 } |
| 114 | 114 |
| 115 bool QuicPacketGenerator::CanSendWithNextPendingFrameAddition() const { |
| 116 DCHECK(HasPendingFrames()); |
| 117 HasRetransmittableData retransmittable = |
| 118 (should_send_ack_ || should_send_feedback_) ? NO_RETRANSMITTABLE_DATA |
| 119 : HAS_RETRANSMITTABLE_DATA; |
| 120 if (retransmittable == HAS_RETRANSMITTABLE_DATA) { |
| 121 DCHECK(!queued_control_frames_.empty()); // These are retransmittable. |
| 122 } |
| 123 return delegate_->CanWrite(NOT_RETRANSMISSION, retransmittable); |
| 124 } |
| 125 |
| 115 void QuicPacketGenerator::SendQueuedFrames() { | 126 void QuicPacketGenerator::SendQueuedFrames() { |
| 116 packet_creator_->MaybeStartFEC(); | 127 packet_creator_->MaybeStartFEC(); |
| 117 while (HasPendingFrames() && delegate_->CanWrite(NOT_RETRANSMISSION, | 128 // Only add pending frames if we are SURE we can then send the whole packet. |
| 118 packet_creator_->HasPendingFrames() ? | 129 while (HasPendingFrames() && CanSendWithNextPendingFrameAddition()) { |
| 119 HAS_RETRANSMITTABLE_DATA : NO_RETRANSMITTABLE_DATA)) { | |
| 120 if (!AddNextPendingFrame()) { | 130 if (!AddNextPendingFrame()) { |
| 121 // Packet was full, so serialize and send it. | 131 // Packet was full, so serialize and send it. |
| 122 SerializeAndSendPacket(); | 132 SerializeAndSendPacket(); |
| 123 } | 133 } |
| 124 } | 134 } |
| 125 | 135 |
| 126 if (should_flush_) { | 136 if (should_flush_) { |
| 127 if (packet_creator_->HasPendingFrames()) { | 137 if (packet_creator_->HasPendingFrames()) { |
| 128 SerializeAndSendPacket(); | 138 SerializeAndSendPacket(); |
| 129 } | 139 } |
| (...skipping 22 matching lines...) Expand all Loading... |
| 152 return packet_creator_->HasPendingFrames() || HasPendingFrames(); | 162 return packet_creator_->HasPendingFrames() || HasPendingFrames(); |
| 153 } | 163 } |
| 154 | 164 |
| 155 bool QuicPacketGenerator::HasPendingFrames() const { | 165 bool QuicPacketGenerator::HasPendingFrames() const { |
| 156 return should_send_ack_ || should_send_feedback_ || | 166 return should_send_ack_ || should_send_feedback_ || |
| 157 !queued_control_frames_.empty(); | 167 !queued_control_frames_.empty(); |
| 158 } | 168 } |
| 159 | 169 |
| 160 bool QuicPacketGenerator::AddNextPendingFrame() { | 170 bool QuicPacketGenerator::AddNextPendingFrame() { |
| 161 if (should_send_ack_) { | 171 if (should_send_ack_) { |
| 162 pending_ack_frame_.reset(delegate_->CreateAckFrame()); | 172 pending_ack_frame_.reset((delegate_->CreateAckFrame())); |
| 163 if (!AddFrame(QuicFrame(pending_ack_frame_.get()))) { | 173 // If we can't this add the frame now, then we still need to do so later. |
| 164 // packet was full | 174 should_send_ack_ = !AddFrame(QuicFrame(pending_ack_frame_.get())); |
| 165 return false; | 175 // Return success if we have cleared out this flag (i.e., added the frame). |
| 166 } | 176 // If we still need to send, then the frame is full, and we have failed. |
| 167 should_send_ack_ = false; | 177 return !should_send_ack_; |
| 168 return true; | |
| 169 } | 178 } |
| 170 | 179 |
| 171 if (should_send_feedback_) { | 180 if (should_send_feedback_) { |
| 172 pending_feedback_frame_.reset(delegate_->CreateFeedbackFrame()); | 181 pending_feedback_frame_.reset((delegate_->CreateFeedbackFrame())); |
| 173 if (!AddFrame(QuicFrame(pending_feedback_frame_.get()))) { | 182 // If we can't this add the frame now, then we still need to do so later. |
| 174 // packet was full | 183 should_send_feedback_ = !AddFrame(QuicFrame(pending_feedback_frame_.get())); |
| 175 return false; | 184 // Return success if we have cleared out this flag (i.e., added the frame). |
| 176 } | 185 // If we still need to send, then the frame is full, and we have failed. |
| 177 should_send_feedback_ = false; | 186 return !should_send_feedback_; |
| 178 return true; | |
| 179 } | 187 } |
| 180 | 188 |
| 181 DCHECK(!queued_control_frames_.empty()); | 189 DCHECK(!queued_control_frames_.empty()); |
| 182 if (!AddFrame(queued_control_frames_.back())) { | 190 if (!AddFrame(queued_control_frames_.back())) { |
| 183 // packet was full | 191 // Packet was full. |
| 184 return false; | 192 return false; |
| 185 } | 193 } |
| 186 queued_control_frames_.pop_back(); | 194 queued_control_frames_.pop_back(); |
| 187 return true; | 195 return true; |
| 188 } | 196 } |
| 189 | 197 |
| 190 bool QuicPacketGenerator::AddFrame(const QuicFrame& frame) { | 198 bool QuicPacketGenerator::AddFrame(const QuicFrame& frame) { |
| 191 bool success = packet_creator_->AddSavedFrame(frame); | 199 bool success = packet_creator_->AddSavedFrame(frame); |
| 192 if (success && debug_delegate_) { | 200 if (success && debug_delegate_) { |
| 193 debug_delegate_->OnFrameAddedToPacket(frame); | 201 debug_delegate_->OnFrameAddedToPacket(frame); |
| 194 } | 202 } |
| 195 return success; | 203 return success; |
| 196 } | 204 } |
| 197 | 205 |
| 198 void QuicPacketGenerator::SerializeAndSendPacket() { | 206 void QuicPacketGenerator::SerializeAndSendPacket() { |
| 199 SerializedPacket serialized_packet = packet_creator_->SerializePacket(); | 207 SerializedPacket serialized_packet = packet_creator_->SerializePacket(); |
| 200 DCHECK(serialized_packet.packet); | 208 DCHECK(serialized_packet.packet); |
| 201 delegate_->OnSerializedPacket(serialized_packet); | 209 delegate_->OnSerializedPacket(serialized_packet); |
| 202 | 210 |
| 203 if (packet_creator_->ShouldSendFec(false)) { | 211 if (packet_creator_->ShouldSendFec(false)) { |
| 204 SerializedPacket serialized_fec = packet_creator_->SerializeFec(); | 212 SerializedPacket serialized_fec = packet_creator_->SerializeFec(); |
| 205 DCHECK(serialized_fec.packet); | 213 DCHECK(serialized_fec.packet); |
| 206 delegate_->OnSerializedPacket(serialized_fec); | 214 delegate_->OnSerializedPacket(serialized_fec); |
| 207 packet_creator_->MaybeStartFEC(); | 215 packet_creator_->MaybeStartFEC(); |
| 208 } | 216 } |
| 209 } | 217 } |
| 210 | 218 |
| 211 } // namespace net | 219 } // namespace net |
| OLD | NEW |