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
3 // found in the LICENSE file.
5 #include "net/spdy/spdy_write_queue.h"
9 #include "base/logging.h"
10 #include "net/spdy/spdy_buffer.h"
11 #include "net/spdy/spdy_buffer_producer.h"
12 #include "net/spdy/spdy_stream.h"
16 SpdyWriteQueue::PendingWrite::PendingWrite() : frame_producer(NULL
) {}
18 SpdyWriteQueue::PendingWrite::PendingWrite(
19 SpdyFrameType frame_type
,
20 SpdyBufferProducer
* frame_producer
,
21 const base::WeakPtr
<SpdyStream
>& stream
)
22 : frame_type(frame_type
),
23 frame_producer(frame_producer
),
25 has_stream(stream
.get() != NULL
) {}
27 SpdyWriteQueue::PendingWrite::~PendingWrite() {}
29 SpdyWriteQueue::SpdyWriteQueue() {}
31 SpdyWriteQueue::~SpdyWriteQueue() {
35 bool SpdyWriteQueue::IsEmpty() const {
36 for (int i
= MINIMUM_PRIORITY
; i
<= MAXIMUM_PRIORITY
; i
++) {
37 if (!queue_
[i
].empty())
43 void SpdyWriteQueue::Enqueue(RequestPriority priority
,
44 SpdyFrameType frame_type
,
45 scoped_ptr
<SpdyBufferProducer
> frame_producer
,
46 const base::WeakPtr
<SpdyStream
>& stream
) {
47 CHECK_GE(priority
, MINIMUM_PRIORITY
);
48 CHECK_LE(priority
, MAXIMUM_PRIORITY
);
50 DCHECK_EQ(stream
->priority(), priority
);
51 queue_
[priority
].push_back(
52 PendingWrite(frame_type
, frame_producer
.release(), stream
));
55 bool SpdyWriteQueue::Dequeue(SpdyFrameType
* frame_type
,
56 scoped_ptr
<SpdyBufferProducer
>* frame_producer
,
57 base::WeakPtr
<SpdyStream
>* stream
) {
58 for (int i
= MAXIMUM_PRIORITY
; i
>= MINIMUM_PRIORITY
; --i
) {
59 if (!queue_
[i
].empty()) {
60 PendingWrite pending_write
= queue_
[i
].front();
61 queue_
[i
].pop_front();
62 *frame_type
= pending_write
.frame_type
;
63 frame_producer
->reset(pending_write
.frame_producer
);
64 *stream
= pending_write
.stream
;
65 if (pending_write
.has_stream
)
66 DCHECK(stream
->get());
73 void SpdyWriteQueue::RemovePendingWritesForStream(
74 const base::WeakPtr
<SpdyStream
>& stream
) {
75 RequestPriority priority
= stream
->priority();
76 CHECK_GE(priority
, MINIMUM_PRIORITY
);
77 CHECK_LE(priority
, MAXIMUM_PRIORITY
);
81 // |stream| should not have pending writes in a queue not matching
83 for (int i
= MINIMUM_PRIORITY
; i
<= MAXIMUM_PRIORITY
; ++i
) {
86 for (std::deque
<PendingWrite
>::const_iterator it
= queue_
[i
].begin();
87 it
!= queue_
[i
].end(); ++it
) {
88 DCHECK_NE(it
->stream
.get(), stream
.get());
93 // Do the actual deletion and removal, preserving FIFO-ness.
94 std::deque
<PendingWrite
>* queue
= &queue_
[priority
];
95 std::deque
<PendingWrite
>::iterator out_it
= queue
->begin();
96 for (std::deque
<PendingWrite
>::const_iterator it
= queue
->begin();
97 it
!= queue
->end(); ++it
) {
98 if (it
->stream
.get() == stream
.get()) {
99 delete it
->frame_producer
;
105 queue
->erase(out_it
, queue
->end());
108 void SpdyWriteQueue::RemovePendingWritesForStreamsAfter(
109 SpdyStreamId last_good_stream_id
) {
110 for (int i
= MINIMUM_PRIORITY
; i
<= MAXIMUM_PRIORITY
; ++i
) {
111 // Do the actual deletion and removal, preserving FIFO-ness.
112 std::deque
<PendingWrite
>* queue
= &queue_
[i
];
113 std::deque
<PendingWrite
>::iterator out_it
= queue
->begin();
114 for (std::deque
<PendingWrite
>::const_iterator it
= queue
->begin();
115 it
!= queue
->end(); ++it
) {
116 if (it
->stream
.get() && (it
->stream
->stream_id() > last_good_stream_id
||
117 it
->stream
->stream_id() == 0)) {
118 delete it
->frame_producer
;
124 queue
->erase(out_it
, queue
->end());
128 void SpdyWriteQueue::Clear() {
129 for (int i
= MINIMUM_PRIORITY
; i
<= MAXIMUM_PRIORITY
; ++i
) {
130 for (std::deque
<PendingWrite
>::iterator it
= queue_
[i
].begin();
131 it
!= queue_
[i
].end(); ++it
) {
132 delete it
->frame_producer
;