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

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

Issue 2193073003: Move shared files in net/quic/ into net/quic/core/ (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: io_thread_unittest.cc Created 4 years, 4 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_stream_sequencer.h ('k') | net/quic/quic_stream_sequencer_buffer.h » ('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_stream_sequencer.h"
6
7 #include <algorithm>
8 #include <limits>
9 #include <string>
10 #include <utility>
11
12 #include "base/logging.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "net/quic/quic_bug_tracker.h"
15 #include "net/quic/quic_clock.h"
16 #include "net/quic/quic_flags.h"
17 #include "net/quic/quic_protocol.h"
18 #include "net/quic/quic_stream_sequencer_buffer.h"
19 #include "net/quic/quic_utils.h"
20 #include "net/quic/reliable_quic_stream.h"
21
22 using base::IntToString;
23 using base::StringPiece;
24 using std::min;
25 using std::numeric_limits;
26 using std::string;
27
28 namespace net {
29
30 QuicStreamSequencer::QuicStreamSequencer(ReliableQuicStream* quic_stream,
31 const QuicClock* clock)
32 : stream_(quic_stream),
33 buffered_frames_(kStreamReceiveWindowLimit),
34 close_offset_(numeric_limits<QuicStreamOffset>::max()),
35 blocked_(false),
36 num_frames_received_(0),
37 num_duplicate_frames_received_(0),
38 num_early_frames_received_(0),
39 clock_(clock),
40 ignore_read_data_(false) {}
41
42 QuicStreamSequencer::~QuicStreamSequencer() {}
43
44 void QuicStreamSequencer::OnStreamFrame(const QuicStreamFrame& frame) {
45 ++num_frames_received_;
46 const QuicStreamOffset byte_offset = frame.offset;
47 const size_t data_len = frame.data_length;
48
49 if (frame.fin) {
50 CloseStreamAtOffset(frame.offset + data_len);
51 if (data_len == 0) {
52 return;
53 }
54 }
55 size_t bytes_written;
56 string error_details;
57 QuicErrorCode result = buffered_frames_.OnStreamData(
58 byte_offset, StringPiece(frame.data_buffer, frame.data_length),
59 clock_->ApproximateNow(), &bytes_written, &error_details);
60 if (result != QUIC_NO_ERROR) {
61 string details = "Stream" + base::Uint64ToString(stream_->id()) + ": " +
62 QuicUtils::ErrorToString(result) + ": " + error_details +
63 "\nPeer Address: " +
64 stream_->PeerAddressOfLatestPacket().ToString();
65 DLOG(WARNING) << QuicUtils::ErrorToString(result);
66 DLOG(WARNING) << details;
67 stream_->CloseConnectionWithDetails(result, details);
68 return;
69 }
70
71 if (bytes_written == 0) {
72 ++num_duplicate_frames_received_;
73 // Silently ignore duplicates.
74 return;
75 }
76
77 if (byte_offset > buffered_frames_.BytesConsumed()) {
78 ++num_early_frames_received_;
79 }
80
81 if (blocked_) {
82 return;
83 }
84
85 if (byte_offset == buffered_frames_.BytesConsumed()) {
86 if (ignore_read_data_) {
87 FlushBufferedFrames();
88 } else {
89 stream_->OnDataAvailable();
90 }
91 }
92 }
93
94 void QuicStreamSequencer::CloseStreamAtOffset(QuicStreamOffset offset) {
95 const QuicStreamOffset kMaxOffset = numeric_limits<QuicStreamOffset>::max();
96
97 // If there is a scheduled close, the new offset should match it.
98 if (close_offset_ != kMaxOffset && offset != close_offset_) {
99 stream_->Reset(QUIC_MULTIPLE_TERMINATION_OFFSETS);
100 return;
101 }
102
103 close_offset_ = offset;
104
105 MaybeCloseStream();
106 }
107
108 bool QuicStreamSequencer::MaybeCloseStream() {
109 if (blocked_ || !IsClosed()) {
110 return false;
111 }
112
113 DVLOG(1) << "Passing up termination, as we've processed "
114 << buffered_frames_.BytesConsumed() << " of " << close_offset_
115 << " bytes.";
116 // This will cause the stream to consume the FIN.
117 // Technically it's an error if |num_bytes_consumed| isn't exactly
118 // equal to |close_offset|, but error handling seems silly at this point.
119 if (ignore_read_data_) {
120 // The sequencer is discarding stream data and must notify the stream on
121 // receipt of a FIN because the consumer won't.
122 stream_->OnFinRead();
123 } else {
124 stream_->OnDataAvailable();
125 }
126 buffered_frames_.Clear();
127 return true;
128 }
129
130 int QuicStreamSequencer::GetReadableRegions(iovec* iov, size_t iov_len) const {
131 DCHECK(!blocked_);
132 return buffered_frames_.GetReadableRegions(iov, iov_len);
133 }
134
135 bool QuicStreamSequencer::GetReadableRegion(iovec* iov,
136 QuicTime* timestamp) const {
137 DCHECK(!blocked_);
138 return buffered_frames_.GetReadableRegion(iov, timestamp);
139 }
140
141 int QuicStreamSequencer::Readv(const struct iovec* iov, size_t iov_len) {
142 DCHECK(!blocked_);
143 size_t bytes_read = buffered_frames_.Readv(iov, iov_len);
144 stream_->AddBytesConsumed(bytes_read);
145 return static_cast<int>(bytes_read);
146 }
147
148 bool QuicStreamSequencer::HasBytesToRead() const {
149 return buffered_frames_.HasBytesToRead();
150 }
151
152 bool QuicStreamSequencer::IsClosed() const {
153 return buffered_frames_.BytesConsumed() >= close_offset_;
154 }
155
156 void QuicStreamSequencer::MarkConsumed(size_t num_bytes_consumed) {
157 DCHECK(!blocked_);
158 bool result = buffered_frames_.MarkConsumed(num_bytes_consumed);
159 if (!result) {
160 QUIC_BUG << "Invalid argument to MarkConsumed."
161 << " expect to consume: " << num_bytes_consumed
162 << ", but not enough bytes available. " << DebugString();
163 stream_->Reset(QUIC_ERROR_PROCESSING_STREAM);
164 return;
165 }
166 stream_->AddBytesConsumed(num_bytes_consumed);
167 }
168
169 void QuicStreamSequencer::SetBlockedUntilFlush() {
170 blocked_ = true;
171 }
172
173 void QuicStreamSequencer::SetUnblocked() {
174 blocked_ = false;
175 if (IsClosed() || HasBytesToRead()) {
176 stream_->OnDataAvailable();
177 }
178 }
179
180 void QuicStreamSequencer::StopReading() {
181 if (ignore_read_data_) {
182 return;
183 }
184 ignore_read_data_ = true;
185 FlushBufferedFrames();
186 }
187
188 void QuicStreamSequencer::FlushBufferedFrames() {
189 DCHECK(ignore_read_data_);
190 size_t bytes_flushed = buffered_frames_.FlushBufferedFrames();
191 DVLOG(1) << "Flushing buffered data at offset "
192 << buffered_frames_.BytesConsumed() << " length " << bytes_flushed
193 << " for stream " << stream_->id();
194 stream_->AddBytesConsumed(bytes_flushed);
195 MaybeCloseStream();
196 }
197
198 size_t QuicStreamSequencer::NumBytesBuffered() const {
199 return buffered_frames_.BytesBuffered();
200 }
201
202 QuicStreamOffset QuicStreamSequencer::NumBytesConsumed() const {
203 return buffered_frames_.BytesConsumed();
204 }
205
206 const string QuicStreamSequencer::DebugString() const {
207 // clang-format off
208 return "QuicStreamSequencer:"
209 "\n bytes buffered: " + IntToString(NumBytesBuffered()) +
210 "\n bytes consumed: " + IntToString( NumBytesConsumed()) +
211 "\n has bytes to read: " + (HasBytesToRead() ? "true" : "false") +
212 "\n frames received: " + IntToString(num_frames_received()) +
213 "\n close offset bytes: " + IntToString( close_offset_) +
214 "\n is closed: " + (IsClosed() ? "true" : "false");
215 // clang-format on
216 }
217
218 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/quic_stream_sequencer.h ('k') | net/quic/quic_stream_sequencer_buffer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698