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

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

Issue 2115033002: Adds QUIC_VERSION_36 which adds support to force HOL blocking between streams for measurement purpo… (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@126085461
Patch Set: typo Created 4 years, 5 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
« no previous file with comments | « net/quic/quic_headers_stream.h ('k') | net/quic/quic_headers_stream_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
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_headers_stream.h" 5 #include "net/quic/quic_headers_stream.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/macros.h" 9 #include "base/macros.h"
10 #include "base/metrics/histogram_macros.h" 10 #include "base/metrics/histogram_macros.h"
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 } 49 }
50 50
51 private: 51 private:
52 const QuicClock* clock_; 52 const QuicClock* clock_;
53 std::unique_ptr<QuicHeadersStream::HpackDebugVisitor> 53 std::unique_ptr<QuicHeadersStream::HpackDebugVisitor>
54 headers_stream_hpack_visitor_; 54 headers_stream_hpack_visitor_;
55 55
56 DISALLOW_COPY_AND_ASSIGN(HeaderTableDebugVisitor); 56 DISALLOW_COPY_AND_ASSIGN(HeaderTableDebugVisitor);
57 }; 57 };
58 58
59 // When forced HOL blocking is enabled, extra bytes in the form of
60 // HTTP/2 DATA frame headers are inserted on the way down to the
61 // session layer. |ForceAckListener| filters the |OnPacketAcked()|
62 // notifications generated by the session layer to not count the extra
63 // bytes. Otherwise, code that is using ack listener on streams might
64 // consider it an error if more bytes are acked than were written to
65 // the stream, it is the case with some internal stats gathering code.
66 class ForceHolAckListener : public QuicAckListenerInterface {
67 public:
68 // |extra_bytes| should be initialized to the size of the HTTP/2
69 // DATA frame header inserted when forced HOL blocking is enabled.
70 ForceHolAckListener(QuicAckListenerInterface* stream_ack_listener,
71 int extra_bytes)
72 : stream_ack_listener_(stream_ack_listener), extra_bytes_(extra_bytes) {
73 DCHECK_GE(extra_bytes, 0);
74 }
75
76 void OnPacketAcked(int acked_bytes, QuicTime::Delta ack_delay_time) override {
77 if (extra_bytes_ > 0) {
78 // Don't count the added HTTP/2 DATA frame header bytes
79 int delta = std::min(extra_bytes_, acked_bytes);
80 extra_bytes_ -= delta;
81 acked_bytes -= delta;
82 }
83 stream_ack_listener_->OnPacketAcked(acked_bytes, ack_delay_time);
84 }
85
86 void OnPacketRetransmitted(int retransmitted_bytes) override {
87 stream_ack_listener_->OnPacketRetransmitted(retransmitted_bytes);
88 }
89
90 private:
91 ~ForceHolAckListener() override {}
92
93 scoped_refptr<QuicAckListenerInterface> stream_ack_listener_;
94 int extra_bytes_;
95
96 DISALLOW_COPY_AND_ASSIGN(ForceHolAckListener);
97 };
98
59 } // namespace 99 } // namespace
60 100
61 QuicHeadersStream::HpackDebugVisitor::HpackDebugVisitor() {} 101 QuicHeadersStream::HpackDebugVisitor::HpackDebugVisitor() {}
62 102
63 QuicHeadersStream::HpackDebugVisitor::~HpackDebugVisitor() {} 103 QuicHeadersStream::HpackDebugVisitor::~HpackDebugVisitor() {}
64 104
65 // A SpdyFramer visitor which passed SYN_STREAM and SYN_REPLY frames to 105 // A SpdyFramer visitor which passed SYN_STREAM and SYN_REPLY frames to
66 // the QuicSpdyStream, and closes the connection if any unexpected frames 106 // the QuicSpdyStream, and closes the connection if any unexpected frames
67 // are received. 107 // are received.
68 class QuicHeadersStream::SpdyFramerVisitor 108 class QuicHeadersStream::SpdyFramerVisitor
(...skipping 21 matching lines...) Expand all
90 if (!stream_->IsConnected()) { 130 if (!stream_->IsConnected()) {
91 return false; 131 return false;
92 } 132 }
93 stream_->OnControlFrameHeaderData(stream_id, header_data, len); 133 stream_->OnControlFrameHeaderData(stream_id, header_data, len);
94 return true; 134 return true;
95 } 135 }
96 136
97 void OnStreamFrameData(SpdyStreamId stream_id, 137 void OnStreamFrameData(SpdyStreamId stream_id,
98 const char* data, 138 const char* data,
99 size_t len) override { 139 size_t len) override {
140 if (stream_->OnStreamFrameData(stream_id, data, len)) {
141 return;
142 }
100 CloseConnection("SPDY DATA frame received."); 143 CloseConnection("SPDY DATA frame received.");
101 } 144 }
102 145
103 void OnStreamEnd(SpdyStreamId stream_id) override { 146 void OnStreamEnd(SpdyStreamId stream_id) override {
104 // The framer invokes OnStreamEnd after processing a SYN_STREAM 147 // The framer invokes OnStreamEnd after processing a SYN_STREAM
105 // or SYN_REPLY frame that had the fin bit set. 148 // or SYN_REPLY frame that had the fin bit set.
106 } 149 }
107 150
108 void OnStreamPadding(SpdyStreamId stream_id, size_t len) override { 151 void OnStreamPadding(SpdyStreamId stream_id, size_t len) override {
109 CloseConnection("SPDY frame padding received."); 152 CloseConnection("SPDY frame padding received.");
(...skipping 16 matching lines...) Expand all
126 169
127 void OnError(SpdyFramer* framer) override { 170 void OnError(SpdyFramer* framer) override {
128 CloseConnection(base::StringPrintf( 171 CloseConnection(base::StringPrintf(
129 "SPDY framing error: %s", 172 "SPDY framing error: %s",
130 SpdyFramer::ErrorCodeToString(framer->error_code()))); 173 SpdyFramer::ErrorCodeToString(framer->error_code())));
131 } 174 }
132 175
133 void OnDataFrameHeader(SpdyStreamId stream_id, 176 void OnDataFrameHeader(SpdyStreamId stream_id,
134 size_t length, 177 size_t length,
135 bool fin) override { 178 bool fin) override {
179 if (stream_->OnDataFrameHeader(stream_id, length, fin)) {
180 return;
181 }
136 CloseConnection("SPDY DATA frame received."); 182 CloseConnection("SPDY DATA frame received.");
137 } 183 }
138 184
139 void OnRstStream(SpdyStreamId stream_id, 185 void OnRstStream(SpdyStreamId stream_id,
140 SpdyRstStreamStatus status) override { 186 SpdyRstStreamStatus status) override {
141 CloseConnection("SPDY RST_STREAM frame received."); 187 CloseConnection("SPDY RST_STREAM frame received.");
142 } 188 }
143 189
144 void OnSetting(SpdySettingsIds id, uint8_t flags, uint32_t value) override { 190 void OnSetting(SpdySettingsIds id, uint8_t flags, uint32_t value) override {
145 if (!FLAGS_quic_respect_http2_settings_frame) { 191 if (!FLAGS_quic_respect_http2_settings_frame) {
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 // PUSH_PROMISE must not be the last frame sent out, at least followed by 369 // PUSH_PROMISE must not be the last frame sent out, at least followed by
324 // response headers. 370 // response headers.
325 push_promise.set_fin(false); 371 push_promise.set_fin(false);
326 372
327 SpdySerializedFrame frame(spdy_framer_.SerializeFrame(push_promise)); 373 SpdySerializedFrame frame(spdy_framer_.SerializeFrame(push_promise));
328 WriteOrBufferData(StringPiece(frame.data(), frame.size()), false, 374 WriteOrBufferData(StringPiece(frame.data(), frame.size()), false,
329 ack_listener); 375 ack_listener);
330 return frame.size(); 376 return frame.size();
331 } 377 }
332 378
379 QuicConsumedData QuicHeadersStream::WritevStreamData(
380 QuicStreamId id,
381 QuicIOVector iov,
382 QuicStreamOffset offset,
383 bool fin,
384 QuicAckListenerInterface* ack_notifier_delegate) {
385 const size_t max_len = SpdyConstants::GetFrameMaximumSize(HTTP2) -
386 SpdyConstants::GetDataFrameMinimumSize(HTTP2);
387
388 QuicConsumedData result(0, false);
389 size_t total_length = iov.total_length;
390
391 // Encapsulate the data into HTTP/2 DATA frames. The outer loop
392 // handles each element of the source iov, the inner loop handles
393 // the possibility of fragmenting eacho of those into multiple DATA
394 // frames, as the DATA frames have a max size of 16KB.
395 for (int i = 0; i < iov.iov_count; i++) {
396 size_t offset = 0;
397 const struct iovec* src_iov = &iov.iov[i];
398 do {
399 size_t len =
400 std::min(std::min(src_iov->iov_len - offset, max_len), total_length);
401 char* data = static_cast<char*>(src_iov->iov_base) + offset;
402 SpdyDataIR spdy_data(id, StringPiece(data, len));
403 offset += len;
404 // fin handling, set it only it only very last generated HTTP/2
405 // DATA frame.
406 bool last_iov = i == iov.iov_count - 1;
407 bool last_fragment_within_iov = offset >= src_iov->iov_len;
408 bool frame_fin = (last_iov && last_fragment_within_iov) ? fin : false;
409 spdy_data.set_fin(frame_fin);
410 if (frame_fin) {
411 result.fin_consumed = true;
412 }
413 SpdySerializedFrame frame(spdy_framer_.SerializeFrame(spdy_data));
414 DVLOG(1) << "Encapsulating in DATA frame for stream " << id << " len "
415 << len << " fin " << spdy_data.fin() << " remaining "
416 << src_iov->iov_len - offset;
417
418 scoped_refptr<ForceHolAckListener> ack_listener;
419 if (ack_notifier_delegate != nullptr) {
420 ack_listener =
421 new ForceHolAckListener(ack_notifier_delegate, frame.size() - len);
422 }
423
424 WriteOrBufferData(StringPiece(frame.data(), frame.size()), false,
425 ack_listener.get());
426 result.bytes_consumed += len;
427 total_length -= len;
428 if (total_length <= 0) {
429 return result;
430 }
431 } while (offset < src_iov->iov_len);
432 }
433 return result;
434 }
435
333 void QuicHeadersStream::OnDataAvailable() { 436 void QuicHeadersStream::OnDataAvailable() {
334 char buffer[1024]; 437 char buffer[1024];
335 struct iovec iov; 438 struct iovec iov;
336 QuicTime timestamp(QuicTime::Zero()); 439 QuicTime timestamp(QuicTime::Zero());
337 while (true) { 440 while (true) {
338 iov.iov_base = buffer; 441 iov.iov_base = buffer;
339 iov.iov_len = arraysize(buffer); 442 iov.iov_len = arraysize(buffer);
340 if (measure_headers_hol_blocking_time_) { 443 if (measure_headers_hol_blocking_time_) {
341 if (!sequencer()->GetReadableRegion(&iov, &timestamp)) { 444 if (!sequencer()->GetReadableRegion(&iov, &timestamp)) {
342 // No more data to read. 445 // No more data to read.
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
499 std::unique_ptr<HpackDebugVisitor> visitor) { 602 std::unique_ptr<HpackDebugVisitor> visitor) {
500 spdy_framer_.SetDecoderHeaderTableDebugVisitor( 603 spdy_framer_.SetDecoderHeaderTableDebugVisitor(
501 std::unique_ptr<HeaderTableDebugVisitor>(new HeaderTableDebugVisitor( 604 std::unique_ptr<HeaderTableDebugVisitor>(new HeaderTableDebugVisitor(
502 session()->connection()->helper()->GetClock(), std::move(visitor)))); 605 session()->connection()->helper()->GetClock(), std::move(visitor))));
503 } 606 }
504 607
505 void QuicHeadersStream::UpdateHeaderEncoderTableSize(uint32_t value) { 608 void QuicHeadersStream::UpdateHeaderEncoderTableSize(uint32_t value) {
506 spdy_framer_.UpdateHeaderEncoderTableSize(value); 609 spdy_framer_.UpdateHeaderEncoderTableSize(value);
507 } 610 }
508 611
612 bool QuicHeadersStream::OnDataFrameHeader(QuicStreamId stream_id,
613 size_t length,
614 bool fin) {
615 if (!spdy_session_->force_hol_blocking()) {
616 return false;
617 }
618 if (!IsConnected()) {
619 return true;
620 }
621 DVLOG(1) << "DATA frame header for stream " << stream_id << " length "
622 << length << " fin " << fin;
623 fin_ = fin;
624 frame_len_ = length;
625 if (fin && length == 0) {
626 OnStreamFrameData(stream_id, "", 0);
627 }
628 return true;
629 }
630
631 bool QuicHeadersStream::OnStreamFrameData(QuicStreamId stream_id,
632 const char* data,
633 size_t len) {
634 if (!spdy_session_->force_hol_blocking()) {
635 return false;
636 }
637 if (!IsConnected()) {
638 return true;
639 }
640 frame_len_ -= len;
641 // Ignore fin_ while there is more data coming, if frame_len_ > 0.
642 spdy_session_->OnStreamFrameData(stream_id, data, len,
643 frame_len_ > 0 ? false : fin_);
644 return true;
645 }
646
509 } // namespace net 647 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/quic_headers_stream.h ('k') | net/quic/quic_headers_stream_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698