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

Side by Side Diff: net/quic/quic_write_blocked_list.h

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_utils_test.cc ('k') | net/quic/quic_write_blocked_list.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 2014 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 #ifndef NET_QUIC_QUIC_WRITE_BLOCKED_LIST_H_
6 #define NET_QUIC_QUIC_WRITE_BLOCKED_LIST_H_
7
8 #include <stddef.h>
9 #include <stdint.h>
10
11 #include <set>
12
13 #include "base/macros.h"
14 #include "net/base/net_export.h"
15 #include "net/quic/quic_flags.h"
16 #include "net/quic/quic_protocol.h"
17 #include "net/spdy/priority_write_scheduler.h"
18
19 namespace net {
20
21 // Keeps tracks of the QUIC streams that have data to write, sorted by
22 // priority. QUIC stream priority order is:
23 // Crypto stream > Headers stream > Data streams by requested priority.
24 class NET_EXPORT_PRIVATE QuicWriteBlockedList {
25 private:
26 typedef PriorityWriteScheduler<QuicStreamId> QuicPriorityWriteScheduler;
27
28 public:
29 QuicWriteBlockedList();
30 ~QuicWriteBlockedList();
31
32 bool HasWriteBlockedDataStreams() const {
33 return priority_write_scheduler_.HasReadyStreams();
34 }
35
36 bool HasWriteBlockedCryptoOrHeadersStream() const {
37 return crypto_stream_blocked_ || headers_stream_blocked_;
38 }
39
40 size_t NumBlockedStreams() const {
41 size_t num_blocked = priority_write_scheduler_.NumReadyStreams();
42 if (crypto_stream_blocked_) {
43 ++num_blocked;
44 }
45 if (headers_stream_blocked_) {
46 ++num_blocked;
47 }
48
49 return num_blocked;
50 }
51
52 bool ShouldYield(QuicStreamId id) const {
53 if (id == kCryptoStreamId) {
54 return false; // The crypto stream yields to none.
55 }
56 if (crypto_stream_blocked_) {
57 return true; // If the crypto stream is blocked, all other streams yield.
58 }
59 if (id == kHeadersStreamId) {
60 return false; // The crypto stream isn't blocked so headers won't yield.
61 }
62 if (headers_stream_blocked_) {
63 return true; // All data streams yield to the headers stream.
64 }
65
66 return priority_write_scheduler_.ShouldYield(id);
67 }
68
69 // Pops the highest priorty stream, special casing crypto and headers streams.
70 // Latches the most recently popped data stream for batch writing purposes.
71 QuicStreamId PopFront() {
72 if (crypto_stream_blocked_) {
73 crypto_stream_blocked_ = false;
74 return kCryptoStreamId;
75 }
76
77 if (headers_stream_blocked_) {
78 headers_stream_blocked_ = false;
79 return kHeadersStreamId;
80 }
81
82 const auto id_and_precedence =
83 priority_write_scheduler_.PopNextReadyStreamAndPrecedence();
84 const QuicStreamId id = std::get<0>(id_and_precedence);
85 const SpdyPriority priority =
86 std::get<1>(id_and_precedence).spdy3_priority();
87
88 if (!priority_write_scheduler_.HasReadyStreams()) {
89 // If no streams are blocked, don't bother latching. This stream will be
90 // the first popped for its priority anyway.
91 batch_write_stream_id_[priority] = 0;
92 last_priority_popped_ = priority;
93 } else if (batch_write_stream_id_[priority] != id) {
94 // If newly latching this batch write stream, let it write 16k.
95 batch_write_stream_id_[priority] = id;
96 bytes_left_for_batch_write_[priority] = 16000;
97 last_priority_popped_ = priority;
98 }
99
100 return id;
101 }
102
103 void RegisterStream(QuicStreamId stream_id, SpdyPriority priority) {
104 priority_write_scheduler_.RegisterStream(stream_id,
105 SpdyStreamPrecedence(priority));
106 }
107
108 void UnregisterStream(QuicStreamId stream_id) {
109 priority_write_scheduler_.UnregisterStream(stream_id);
110 }
111
112 void UpdateStreamPriority(QuicStreamId stream_id, SpdyPriority new_priority) {
113 priority_write_scheduler_.UpdateStreamPrecedence(
114 stream_id, SpdyStreamPrecedence(new_priority));
115 }
116
117 void UpdateBytesForStream(QuicStreamId stream_id, size_t bytes) {
118 if (batch_write_stream_id_[last_priority_popped_] == stream_id) {
119 // If this was the last data stream popped by PopFront, update the
120 // bytes remaining in its batch write.
121 bytes_left_for_batch_write_[last_priority_popped_] -=
122 static_cast<int32_t>(bytes);
123 }
124 }
125
126 // Pushes a stream to the back of the list for its priority level *unless*
127 // it is latched for doing batched writes in which case it goes to the front
128 // of the list for its priority level.
129 // Headers and crypto streams are special cased to always resume first.
130 void AddStream(QuicStreamId stream_id) {
131 if (stream_id == kCryptoStreamId) {
132 // TODO(avd) Add DCHECK(!crypto_stream_blocked_)
133 crypto_stream_blocked_ = true;
134 return;
135 }
136
137 if (stream_id == kHeadersStreamId) {
138 // TODO(avd) Add DCHECK(!headers_stream_blocked_);
139 headers_stream_blocked_ = true;
140 return;
141 }
142 bool push_front =
143 stream_id == batch_write_stream_id_[last_priority_popped_] &&
144 bytes_left_for_batch_write_[last_priority_popped_] > 0;
145 priority_write_scheduler_.MarkStreamReady(stream_id, push_front);
146
147 return;
148 }
149
150 bool crypto_stream_blocked() const { return crypto_stream_blocked_; }
151 bool headers_stream_blocked() const { return headers_stream_blocked_; }
152
153 private:
154 QuicPriorityWriteScheduler priority_write_scheduler_;
155
156 // If performing batch writes, this will be the stream ID of the stream doing
157 // batch writes for this priority level. We will allow this stream to write
158 // until it has written kBatchWriteSize bytes, it has no more data to write,
159 // or a higher priority stream preempts.
160 QuicStreamId batch_write_stream_id_[kV3LowestPriority + 1];
161 // Set to kBatchWriteSize when we set a new batch_write_stream_id_ for a given
162 // priority. This is decremented with each write the stream does until it is
163 // done with its batch write.
164 int32_t bytes_left_for_batch_write_[kV3LowestPriority + 1];
165 // Tracks the last priority popped for UpdateBytesForStream.
166 SpdyPriority last_priority_popped_;
167
168 bool crypto_stream_blocked_;
169 bool headers_stream_blocked_;
170
171 DISALLOW_COPY_AND_ASSIGN(QuicWriteBlockedList);
172 };
173
174 } // namespace net
175
176 #endif // NET_QUIC_QUIC_WRITE_BLOCKED_LIST_H_
OLDNEW
« no previous file with comments | « net/quic/quic_utils_test.cc ('k') | net/quic/quic_write_blocked_list.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698