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
3 // found in the LICENSE file.
5 #ifndef NET_SPDY_WRITE_BLOCKED_LIST_H_
6 #define NET_SPDY_WRITE_BLOCKED_LIST_H_
11 #include "base/logging.h"
12 #include "net/spdy/spdy_protocol.h"
15 class WriteBlockedListPeer
;
20 const int kHighestPriority
= 0;
21 const int kLowestPriority
= 7;
23 template <typename IdType
>
24 class WriteBlockedList
{
26 // 0(1) size lookup. 0(1) insert at front or back.
27 typedef std::deque
<IdType
> BlockedList
;
28 typedef typename
BlockedList::iterator iterator
;
30 static SpdyPriority
ClampPriority(SpdyPriority priority
) {
31 if (priority
< kHighestPriority
) {
32 LOG(DFATAL
) << "Invalid priority: " << static_cast<int>(priority
);
33 return kHighestPriority
;
35 if (priority
> kLowestPriority
) {
36 LOG(DFATAL
) << "Invalid priority: " << static_cast<int>(priority
);
37 return kLowestPriority
;
42 // Returns the priority of the highest priority list with sessions on it.
43 SpdyPriority
GetHighestPriorityWriteBlockedList() const {
44 for (SpdyPriority i
= 0; i
<= kLowestPriority
; ++i
) {
45 if (write_blocked_lists_
[i
].size() > 0)
48 LOG(DFATAL
) << "No blocked streams";
49 return kHighestPriority
;
52 IdType
PopFront(SpdyPriority priority
) {
53 priority
= ClampPriority(priority
);
54 DCHECK(!write_blocked_lists_
[priority
].empty());
55 IdType stream_id
= write_blocked_lists_
[priority
].front();
56 write_blocked_lists_
[priority
].pop_front();
60 bool HasWriteBlockedStreamsGreaterThanPriority(SpdyPriority priority
) const {
61 priority
= ClampPriority(priority
);
62 for (SpdyPriority i
= kHighestPriority
; i
< priority
; ++i
) {
63 if (!write_blocked_lists_
[i
].empty()) {
70 bool HasWriteBlockedStreams() const {
71 for (SpdyPriority i
= kHighestPriority
; i
<= kLowestPriority
; ++i
) {
72 if (!write_blocked_lists_
[i
].empty()) {
79 void PushBack(IdType stream_id
, SpdyPriority priority
) {
80 write_blocked_lists_
[ClampPriority(priority
)].push_back(stream_id
);
83 bool RemoveStreamFromWriteBlockedList(IdType stream_id
,
84 SpdyPriority priority
) {
85 // We shouldn't really add a stream_id to a list multiple times,
86 // but under some conditions it does happen. Doing a check in PushBack
87 // would be too costly, so instead we check here to eliminate duplicates.
89 iterator it
= std::find(write_blocked_lists_
[priority
].begin(),
90 write_blocked_lists_
[priority
].end(),
92 while (it
!= write_blocked_lists_
[priority
].end()) {
94 iterator next_it
= write_blocked_lists_
[priority
].erase(it
);
95 it
= std::find(next_it
, write_blocked_lists_
[priority
].end(), stream_id
);
100 void UpdateStreamPriorityInWriteBlockedList(IdType stream_id
,
101 SpdyPriority old_priority
,
102 SpdyPriority new_priority
) {
103 if (old_priority
== new_priority
) {
106 bool found
= RemoveStreamFromWriteBlockedList(stream_id
, old_priority
);
108 PushBack(stream_id
, new_priority
);
112 size_t NumBlockedStreams() const {
113 size_t num_blocked_streams
= 0;
114 for (SpdyPriority i
= kHighestPriority
; i
<= kLowestPriority
; ++i
) {
115 num_blocked_streams
+= write_blocked_lists_
[i
].size();
117 return num_blocked_streams
;
121 friend WriteBlockedListPeer
;
122 BlockedList write_blocked_lists_
[kLowestPriority
+ 1];
127 #endif // NET_SPDY_WRITE_BLOCKED_LIST_H_