OLD | NEW |
---|---|
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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 #include "net/spdy/spdy_write_queue.h" | 5 #include "net/spdy/spdy_write_queue.h" |
6 | 6 |
7 #include <cstddef> | 7 #include <cstddef> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "net/spdy/spdy_buffer.h" | 10 #include "net/spdy/spdy_buffer.h" |
11 #include "net/spdy/spdy_buffer_producer.h" | 11 #include "net/spdy/spdy_buffer_producer.h" |
12 #include "net/spdy/spdy_stream.h" | 12 #include "net/spdy/spdy_stream.h" |
13 | 13 |
14 namespace net { | 14 namespace net { |
15 | 15 |
16 SpdyWriteQueue::PendingWrite::PendingWrite() : frame_producer(NULL) {} | 16 SpdyWriteQueue::PendingWrite::PendingWrite() : frame_producer(NULL) {} |
17 | 17 |
18 SpdyWriteQueue::PendingWrite::PendingWrite( | 18 SpdyWriteQueue::PendingWrite::PendingWrite( |
19 SpdyFrameType frame_type, | 19 SpdyFrameType frame_type, |
20 SpdyBufferProducer* frame_producer, | 20 SpdyBufferProducer* frame_producer, |
21 const base::WeakPtr<SpdyStream>& stream) | 21 const base::WeakPtr<SpdyStream>& stream) |
22 : frame_type(frame_type), | 22 : frame_type(frame_type), |
23 frame_producer(frame_producer), | 23 frame_producer(frame_producer), |
24 stream(stream), | 24 stream(stream), |
25 has_stream(stream.get() != NULL) {} | 25 has_stream(stream.get() != NULL) {} |
26 | 26 |
27 SpdyWriteQueue::PendingWrite::~PendingWrite() {} | 27 SpdyWriteQueue::PendingWrite::~PendingWrite() {} |
28 | 28 |
29 SpdyWriteQueue::SpdyWriteQueue() {} | 29 SpdyWriteQueue::SpdyWriteQueue() : removing_writes_(false) {} |
30 | 30 |
31 SpdyWriteQueue::~SpdyWriteQueue() { | 31 SpdyWriteQueue::~SpdyWriteQueue() { |
32 Clear(); | 32 Clear(); |
33 } | 33 } |
34 | 34 |
35 bool SpdyWriteQueue::IsEmpty() const { | 35 bool SpdyWriteQueue::IsEmpty() const { |
36 for (int i = MINIMUM_PRIORITY; i <= MAXIMUM_PRIORITY; i++) { | 36 for (int i = MINIMUM_PRIORITY; i <= MAXIMUM_PRIORITY; i++) { |
37 if (!queue_[i].empty()) | 37 if (!queue_[i].empty()) |
38 return false; | 38 return false; |
39 } | 39 } |
40 return true; | 40 return true; |
41 } | 41 } |
42 | 42 |
43 void SpdyWriteQueue::Enqueue(RequestPriority priority, | 43 void SpdyWriteQueue::Enqueue(RequestPriority priority, |
44 SpdyFrameType frame_type, | 44 SpdyFrameType frame_type, |
45 scoped_ptr<SpdyBufferProducer> frame_producer, | 45 scoped_ptr<SpdyBufferProducer> frame_producer, |
46 const base::WeakPtr<SpdyStream>& stream) { | 46 const base::WeakPtr<SpdyStream>& stream) { |
47 CHECK_GE(priority, MINIMUM_PRIORITY); | 47 CHECK_GE(priority, MINIMUM_PRIORITY); |
48 CHECK_LE(priority, MAXIMUM_PRIORITY); | 48 CHECK_LE(priority, MAXIMUM_PRIORITY); |
49 if (stream.get()) | 49 if (stream.get()) |
50 DCHECK_EQ(stream->priority(), priority); | 50 DCHECK_EQ(stream->priority(), priority); |
51 queue_[priority].push_back( | 51 queue_[priority].push_back( |
52 PendingWrite(frame_type, frame_producer.release(), stream)); | 52 PendingWrite(frame_type, frame_producer.release(), stream)); |
53 } | 53 } |
54 | 54 |
55 bool SpdyWriteQueue::Dequeue(SpdyFrameType* frame_type, | 55 bool SpdyWriteQueue::Dequeue(SpdyFrameType* frame_type, |
56 scoped_ptr<SpdyBufferProducer>* frame_producer, | 56 scoped_ptr<SpdyBufferProducer>* frame_producer, |
57 base::WeakPtr<SpdyStream>* stream) { | 57 base::WeakPtr<SpdyStream>* stream) { |
58 CHECK(!removing_writes_); | |
58 for (int i = MAXIMUM_PRIORITY; i >= MINIMUM_PRIORITY; --i) { | 59 for (int i = MAXIMUM_PRIORITY; i >= MINIMUM_PRIORITY; --i) { |
59 if (!queue_[i].empty()) { | 60 if (!queue_[i].empty()) { |
60 PendingWrite pending_write = queue_[i].front(); | 61 PendingWrite pending_write = queue_[i].front(); |
61 queue_[i].pop_front(); | 62 queue_[i].pop_front(); |
62 *frame_type = pending_write.frame_type; | 63 *frame_type = pending_write.frame_type; |
63 frame_producer->reset(pending_write.frame_producer); | 64 frame_producer->reset(pending_write.frame_producer); |
64 *stream = pending_write.stream; | 65 *stream = pending_write.stream; |
65 if (pending_write.has_stream) | 66 if (pending_write.has_stream) |
66 DCHECK(stream->get()); | 67 DCHECK(stream->get()); |
67 return true; | 68 return true; |
68 } | 69 } |
69 } | 70 } |
70 return false; | 71 return false; |
71 } | 72 } |
72 | 73 |
73 void SpdyWriteQueue::RemovePendingWritesForStream( | 74 void SpdyWriteQueue::RemovePendingWritesForStream( |
74 const base::WeakPtr<SpdyStream>& stream) { | 75 const base::WeakPtr<SpdyStream>& stream) { |
76 CHECK(!removing_writes_); | |
77 removing_writes_ = true; | |
75 RequestPriority priority = stream->priority(); | 78 RequestPriority priority = stream->priority(); |
76 CHECK_GE(priority, MINIMUM_PRIORITY); | 79 CHECK_GE(priority, MINIMUM_PRIORITY); |
77 CHECK_LE(priority, MAXIMUM_PRIORITY); | 80 CHECK_LE(priority, MAXIMUM_PRIORITY); |
78 | 81 |
79 DCHECK(stream.get()); | 82 DCHECK(stream.get()); |
80 #if DCHECK_IS_ON | 83 #if DCHECK_IS_ON |
81 // |stream| should not have pending writes in a queue not matching | 84 // |stream| should not have pending writes in a queue not matching |
82 // its priority. | 85 // its priority. |
83 for (int i = MINIMUM_PRIORITY; i <= MAXIMUM_PRIORITY; ++i) { | 86 for (int i = MINIMUM_PRIORITY; i <= MAXIMUM_PRIORITY; ++i) { |
84 if (priority == i) | 87 if (priority == i) |
(...skipping 11 matching lines...) Expand all Loading... | |
96 for (std::deque<PendingWrite>::const_iterator it = queue->begin(); | 99 for (std::deque<PendingWrite>::const_iterator it = queue->begin(); |
97 it != queue->end(); ++it) { | 100 it != queue->end(); ++it) { |
98 if (it->stream.get() == stream.get()) { | 101 if (it->stream.get() == stream.get()) { |
99 delete it->frame_producer; | 102 delete it->frame_producer; |
100 } else { | 103 } else { |
101 *out_it = *it; | 104 *out_it = *it; |
102 ++out_it; | 105 ++out_it; |
103 } | 106 } |
104 } | 107 } |
105 queue->erase(out_it, queue->end()); | 108 queue->erase(out_it, queue->end()); |
109 removing_writes_ = false; | |
106 } | 110 } |
107 | 111 |
108 void SpdyWriteQueue::RemovePendingWritesForStreamsAfter( | 112 void SpdyWriteQueue::RemovePendingWritesForStreamsAfter( |
109 SpdyStreamId last_good_stream_id) { | 113 SpdyStreamId last_good_stream_id) { |
114 CHECK(!removing_writes_); | |
115 removing_writes_ = true; | |
110 for (int i = MINIMUM_PRIORITY; i <= MAXIMUM_PRIORITY; ++i) { | 116 for (int i = MINIMUM_PRIORITY; i <= MAXIMUM_PRIORITY; ++i) { |
111 // Do the actual deletion and removal, preserving FIFO-ness. | 117 // Do the actual deletion and removal, preserving FIFO-ness. |
112 std::deque<PendingWrite>* queue = &queue_[i]; | 118 std::deque<PendingWrite>* queue = &queue_[i]; |
113 std::deque<PendingWrite>::iterator out_it = queue->begin(); | 119 std::deque<PendingWrite>::iterator out_it = queue->begin(); |
114 for (std::deque<PendingWrite>::const_iterator it = queue->begin(); | 120 for (std::deque<PendingWrite>::const_iterator it = queue->begin(); |
115 it != queue->end(); ++it) { | 121 it != queue->end(); ++it) { |
116 if (it->stream.get() && (it->stream->stream_id() > last_good_stream_id || | 122 if (it->stream.get() && (it->stream->stream_id() > last_good_stream_id || |
117 it->stream->stream_id() == 0)) { | 123 it->stream->stream_id() == 0)) { |
118 delete it->frame_producer; | 124 delete it->frame_producer; |
119 } else { | 125 } else { |
120 *out_it = *it; | 126 *out_it = *it; |
121 ++out_it; | 127 ++out_it; |
122 } | 128 } |
123 } | 129 } |
124 queue->erase(out_it, queue->end()); | 130 queue->erase(out_it, queue->end()); |
125 } | 131 } |
132 removing_writes_ = false; | |
126 } | 133 } |
127 | 134 |
128 void SpdyWriteQueue::Clear() { | 135 void SpdyWriteQueue::Clear() { |
136 CHECK(!removing_writes_); | |
Johnny
2014/05/02 21:16:32
Think we should have removing_writes_ = true here.
willchan no longer on Chromium
2014/05/02 21:21:24
Done.
| |
129 for (int i = MINIMUM_PRIORITY; i <= MAXIMUM_PRIORITY; ++i) { | 137 for (int i = MINIMUM_PRIORITY; i <= MAXIMUM_PRIORITY; ++i) { |
130 for (std::deque<PendingWrite>::iterator it = queue_[i].begin(); | 138 for (std::deque<PendingWrite>::iterator it = queue_[i].begin(); |
131 it != queue_[i].end(); ++it) { | 139 it != queue_[i].end(); ++it) { |
132 delete it->frame_producer; | 140 delete it->frame_producer; |
133 } | 141 } |
134 queue_[i].clear(); | 142 queue_[i].clear(); |
135 } | 143 } |
136 } | 144 } |
137 | 145 |
138 } // namespace net | 146 } // namespace net |
OLD | NEW |