OLD | NEW |
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 #ifndef NET_SPDY_WRITE_BLOCKED_LIST_H_ | 5 #ifndef NET_SPDY_WRITE_BLOCKED_LIST_H_ |
6 #define NET_SPDY_WRITE_BLOCKED_LIST_H_ | 6 #define NET_SPDY_WRITE_BLOCKED_LIST_H_ |
7 | 7 |
8 #include <algorithm> | 8 #include <algorithm> |
9 #include <deque> | 9 #include <deque> |
10 | 10 |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "net/spdy/spdy_protocol.h" |
12 | 13 |
13 namespace net { | 14 namespace net { |
14 | 15 |
15 const int kHighestPriority = 0; | 16 const int kHighestPriority = 0; |
16 const int kLowestPriority = 7; | 17 const int kLowestPriority = 7; |
17 | 18 |
18 template <typename IdType> | 19 template <typename IdType> |
19 class WriteBlockedList { | 20 class WriteBlockedList { |
20 public: | 21 public: |
21 // 0(1) size lookup. 0(1) insert at front or back. | 22 // 0(1) size lookup. 0(1) insert at front or back. |
22 typedef std::deque<IdType> BlockedList; | 23 typedef std::deque<IdType> BlockedList; |
23 typedef typename BlockedList::iterator iterator; | 24 typedef typename BlockedList::iterator iterator; |
24 | 25 |
25 // Returns the priority of the highest priority list with sessions on it, or | 26 static SpdyPriority ClampPriority(SpdyPriority priority) { |
26 // -1 if none of the lists have pending sessions. | 27 if (priority < kHighestPriority) { |
27 int GetHighestPriorityWriteBlockedList() const { | 28 LOG(DFATAL) << "Invalid priority: " << static_cast<int>(priority); |
28 for (int i = 0; i <= kLowestPriority; ++i) { | 29 return kHighestPriority; |
| 30 } |
| 31 if (priority > kLowestPriority) { |
| 32 LOG(DFATAL) << "Invalid priority: " << static_cast<int>(priority); |
| 33 return kLowestPriority; |
| 34 } |
| 35 return priority; |
| 36 } |
| 37 |
| 38 // Returns the priority of the highest priority list with sessions on it. |
| 39 SpdyPriority GetHighestPriorityWriteBlockedList() const { |
| 40 for (SpdyPriority i = 0; i <= kLowestPriority; ++i) { |
29 if (write_blocked_lists_[i].size() > 0) | 41 if (write_blocked_lists_[i].size() > 0) |
30 return i; | 42 return i; |
31 } | 43 } |
32 return -1; | 44 LOG(DFATAL) << "No blocked streams"; |
| 45 return kHighestPriority; |
33 } | 46 } |
34 | 47 |
35 int PopFront(int priority) { | 48 IdType PopFront(SpdyPriority priority) { |
| 49 priority = ClampPriority(priority); |
36 DCHECK(!write_blocked_lists_[priority].empty()); | 50 DCHECK(!write_blocked_lists_[priority].empty()); |
37 IdType stream_id = write_blocked_lists_[priority].front(); | 51 IdType stream_id = write_blocked_lists_[priority].front(); |
38 write_blocked_lists_[priority].pop_front(); | 52 write_blocked_lists_[priority].pop_front(); |
39 return stream_id; | 53 return stream_id; |
40 } | 54 } |
41 | 55 |
42 bool HasWriteBlockedStreamsGreaterThanPriority(int priority) const { | 56 bool HasWriteBlockedStreamsGreaterThanPriority(SpdyPriority priority) const { |
43 for (int i = kHighestPriority; i < priority; ++i) { | 57 priority = ClampPriority(priority); |
| 58 for (SpdyPriority i = kHighestPriority; i < priority; ++i) { |
44 if (!write_blocked_lists_[i].empty()) { | 59 if (!write_blocked_lists_[i].empty()) { |
45 return true; | 60 return true; |
46 } | 61 } |
47 } | 62 } |
48 return false; | 63 return false; |
49 } | 64 } |
50 | 65 |
51 bool HasWriteBlockedStreams() const { | 66 bool HasWriteBlockedStreams() const { |
52 return HasWriteBlockedStreamsGreaterThanPriority(kLowestPriority + 1); | 67 for (SpdyPriority i = kHighestPriority; i <= kLowestPriority; ++i) { |
| 68 if (!write_blocked_lists_[i].empty()) { |
| 69 return true; |
| 70 } |
| 71 } |
| 72 return false; |
53 } | 73 } |
54 | 74 |
55 void PushBack(IdType stream_id, int priority) { | 75 void PushBack(IdType stream_id, SpdyPriority priority) { |
56 write_blocked_lists_[priority].push_back(stream_id); | 76 write_blocked_lists_[ClampPriority(priority)].push_back(stream_id); |
57 } | 77 } |
58 | 78 |
59 void RemoveStreamFromWriteBlockedList(IdType stream_id, int priority) { | 79 void RemoveStreamFromWriteBlockedList(IdType stream_id, |
| 80 SpdyPriority priority) { |
60 iterator it = std::find(write_blocked_lists_[priority].begin(), | 81 iterator it = std::find(write_blocked_lists_[priority].begin(), |
61 write_blocked_lists_[priority].end(), | 82 write_blocked_lists_[priority].end(), |
62 stream_id); | 83 stream_id); |
63 while (it != write_blocked_lists_[priority].end()) { | 84 while (it != write_blocked_lists_[priority].end()) { |
64 write_blocked_lists_[priority].erase(it); | 85 write_blocked_lists_[priority].erase(it); |
65 it = std::find(write_blocked_lists_[priority].begin(), | 86 it = std::find(write_blocked_lists_[priority].begin(), |
66 write_blocked_lists_[priority].end(), | 87 write_blocked_lists_[priority].end(), |
67 stream_id); | 88 stream_id); |
68 } | 89 } |
69 } | 90 } |
70 | 91 |
71 int NumBlockedStreams() { | 92 size_t NumBlockedStreams() const { |
72 int num_blocked_streams = 0; | 93 size_t num_blocked_streams = 0; |
73 for (int i = kHighestPriority; i <= kLowestPriority; ++i) { | 94 for (SpdyPriority i = kHighestPriority; i <= kLowestPriority; ++i) { |
74 num_blocked_streams += write_blocked_lists_[i].size(); | 95 num_blocked_streams += write_blocked_lists_[i].size(); |
75 } | 96 } |
76 return num_blocked_streams; | 97 return num_blocked_streams; |
77 } | 98 } |
78 | 99 |
79 private: | 100 private: |
80 // Priority ranges from 0 to 7 | 101 BlockedList write_blocked_lists_[kLowestPriority + 1]; |
81 BlockedList write_blocked_lists_[8]; | |
82 }; | 102 }; |
83 | 103 |
84 } // namespace net | 104 } // namespace net |
85 | 105 |
86 #endif // NET_SPDY_WRITE_BLOCKED_LIST_H_ | 106 #endif // NET_SPDY_WRITE_BLOCKED_LIST_H_ |
OLD | NEW |