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 <set> 9 10 #include "net/base/net_export.h" 11 #include "net/quic/quic_protocol.h" 12 #include "net/spdy/write_blocked_list.h" 13 14 namespace net { 15 16 // Keeps tracks of the QUIC streams that have data to write, sorted by 17 // priority. QUIC stream priority order is: 18 // Crypto stream > Headers stream > Data streams by requested priority. 19 class NET_EXPORT_PRIVATE QuicWriteBlockedList { 20 private: 21 typedef WriteBlockedList<QuicStreamId> QuicWriteBlockedListBase; 22 23 public: 24 static const QuicPriority kHighestPriority; 25 static const QuicPriority kLowestPriority; 26 27 QuicWriteBlockedList(); 28 ~QuicWriteBlockedList(); 29 HasWriteBlockedDataStreams()30 bool HasWriteBlockedDataStreams() const { 31 return base_write_blocked_list_.HasWriteBlockedStreams(); 32 } 33 HasWriteBlockedCryptoOrHeadersStream()34 bool HasWriteBlockedCryptoOrHeadersStream() const { 35 return crypto_stream_blocked_ || headers_stream_blocked_; 36 } 37 NumBlockedStreams()38 size_t NumBlockedStreams() const { 39 size_t num_blocked = base_write_blocked_list_.NumBlockedStreams(); 40 if (crypto_stream_blocked_) { 41 ++num_blocked; 42 } 43 if (headers_stream_blocked_) { 44 ++num_blocked; 45 } 46 47 return num_blocked; 48 } 49 PopFront()50 QuicStreamId PopFront() { 51 if (crypto_stream_blocked_) { 52 crypto_stream_blocked_ = false; 53 return kCryptoStreamId; 54 } 55 56 if (headers_stream_blocked_) { 57 headers_stream_blocked_ = false; 58 return kHeadersStreamId; 59 } 60 61 SpdyPriority priority = 62 base_write_blocked_list_.GetHighestPriorityWriteBlockedList(); 63 QuicStreamId id = base_write_blocked_list_.PopFront(priority); 64 blocked_streams_.erase(id); 65 return id; 66 } 67 PushBack(QuicStreamId stream_id,QuicPriority priority)68 void PushBack(QuicStreamId stream_id, QuicPriority priority) { 69 if (stream_id == kCryptoStreamId) { 70 DCHECK_EQ(kHighestPriority, priority); 71 // TODO(avd) Add DCHECK(!crypto_stream_blocked_) 72 crypto_stream_blocked_ = true; 73 return; 74 } 75 76 if (stream_id == kHeadersStreamId) { 77 DCHECK_EQ(kHighestPriority, priority); 78 // TODO(avd) Add DCHECK(!headers_stream_blocked_); 79 headers_stream_blocked_ = true; 80 return; 81 } 82 83 if (blocked_streams_.find(stream_id) != blocked_streams_.end()) { 84 DVLOG(1) << "Stream " << stream_id << " already in write blocked list."; 85 return; 86 } 87 88 base_write_blocked_list_.PushBack( 89 stream_id, static_cast<SpdyPriority>(priority)); 90 blocked_streams_.insert(stream_id); 91 return; 92 } 93 crypto_stream_blocked()94 bool crypto_stream_blocked() const { return crypto_stream_blocked_; } headers_stream_blocked()95 bool headers_stream_blocked() const { return headers_stream_blocked_; } 96 97 private: 98 QuicWriteBlockedListBase base_write_blocked_list_; 99 bool crypto_stream_blocked_; 100 bool headers_stream_blocked_; 101 102 // Keep track of write blocked streams in a set for faster membership checking 103 // than iterating over the base_write_blocked_list_. The contents of this set 104 // should mirror the contents of base_write_blocked_list_. 105 std::set<QuicStreamId> blocked_streams_; 106 107 DISALLOW_COPY_AND_ASSIGN(QuicWriteBlockedList); 108 }; 109 110 } // namespace net 111 112 113 #endif // NET_QUIC_QUIC_WRITE_BLOCKED_LIST_H_ 114