| Index: net/quic/quic_packet_generator.cc
|
| diff --git a/net/quic/quic_packet_generator.cc b/net/quic/quic_packet_generator.cc
|
| index 34c65e032f903987b573e41d6797fa6e53285e42..cd2013e24f79826ea317092525eb4d7c701570b3 100644
|
| --- a/net/quic/quic_packet_generator.cc
|
| +++ b/net/quic/quic_packet_generator.cc
|
| @@ -23,7 +23,8 @@ QuicPacketGenerator::QuicPacketGenerator(DelegateInterface* delegate,
|
| packet_creator_(creator),
|
| batch_mode_(false),
|
| should_send_ack_(false),
|
| - should_send_feedback_(false) {
|
| + should_send_feedback_(false),
|
| + should_send_stop_waiting_(false) {
|
| }
|
|
|
| QuicPacketGenerator::~QuicPacketGenerator() {
|
| @@ -57,15 +58,25 @@ QuicPacketGenerator::~QuicPacketGenerator() {
|
| case BLOCKED_FRAME:
|
| delete it->blocked_frame;
|
| break;
|
| + case STOP_WAITING_FRAME:
|
| + delete it->stop_waiting_frame;
|
| + break;
|
| case NUM_FRAME_TYPES:
|
| DCHECK(false) << "Cannot delete type: " << it->type;
|
| }
|
| }
|
| }
|
|
|
| -void QuicPacketGenerator::SetShouldSendAck(bool also_send_feedback) {
|
| +void QuicPacketGenerator::SetShouldSendAck(bool also_send_feedback,
|
| + bool also_send_stop_waiting) {
|
| should_send_ack_ = true;
|
| should_send_feedback_ = also_send_feedback;
|
| + should_send_stop_waiting_ = also_send_stop_waiting;
|
| + SendQueuedFrames(false);
|
| +}
|
| +
|
| +void QuicPacketGenerator::SetShouldSendStopWaiting() {
|
| + should_send_stop_waiting_ = true;
|
| SendQueuedFrames(false);
|
| }
|
|
|
| @@ -147,8 +158,8 @@ QuicConsumedData QuicPacketGenerator::ConsumeData(QuicStreamId id,
|
| bool QuicPacketGenerator::CanSendWithNextPendingFrameAddition() const {
|
| DCHECK(HasPendingFrames());
|
| HasRetransmittableData retransmittable =
|
| - (should_send_ack_ || should_send_feedback_) ? NO_RETRANSMITTABLE_DATA
|
| - : HAS_RETRANSMITTABLE_DATA;
|
| + (should_send_ack_ || should_send_feedback_ || should_send_stop_waiting_)
|
| + ? NO_RETRANSMITTABLE_DATA : HAS_RETRANSMITTABLE_DATA;
|
| if (retransmittable == HAS_RETRANSMITTABLE_DATA) {
|
| DCHECK(!queued_control_frames_.empty()); // These are retransmittable.
|
| }
|
| @@ -204,7 +215,7 @@ bool QuicPacketGenerator::HasQueuedFrames() const {
|
|
|
| bool QuicPacketGenerator::HasPendingFrames() const {
|
| return should_send_ack_ || should_send_feedback_ ||
|
| - !queued_control_frames_.empty();
|
| + should_send_stop_waiting_ || !queued_control_frames_.empty();
|
| }
|
|
|
| bool QuicPacketGenerator::AddNextPendingFrame() {
|
| @@ -226,9 +237,18 @@ bool QuicPacketGenerator::AddNextPendingFrame() {
|
| return !should_send_feedback_;
|
| }
|
|
|
| - if (queued_control_frames_.empty()) {
|
| - LOG(DFATAL) << "AddNextPendingFrame called with no queued control frames.";
|
| + if (should_send_stop_waiting_) {
|
| + pending_stop_waiting_frame_.reset(delegate_->CreateStopWaitingFrame());
|
| + // If we can't this add the frame now, then we still need to do so later.
|
| + should_send_stop_waiting_ =
|
| + !AddFrame(QuicFrame(pending_stop_waiting_frame_.get()));
|
| + // Return success if we have cleared out this flag (i.e., added the frame).
|
| + // If we still need to send, then the frame is full, and we have failed.
|
| + return !should_send_stop_waiting_;
|
| }
|
| +
|
| + LOG_IF(DFATAL, queued_control_frames_.empty())
|
| + << "AddNextPendingFrame called with no queued control frames.";
|
| if (!AddFrame(queued_control_frames_.back())) {
|
| // Packet was full.
|
| return false;
|
|
|