• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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