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 scoped_refptr
<SpdyStream
>& stream
)
22 : frame_type(frame_type
),
23 frame_producer(frame_producer
),
26 SpdyWriteQueue::PendingWrite::~PendingWrite() {}
28 SpdyWriteQueue::SpdyWriteQueue() {}
30 SpdyWriteQueue::~SpdyWriteQueue() {
34 void SpdyWriteQueue::Enqueue(RequestPriority priority
,
35 SpdyFrameType frame_type
,
36 scoped_ptr
<SpdyBufferProducer
> frame_producer
,
37 const scoped_refptr
<SpdyStream
>& stream
) {
39 DCHECK_EQ(stream
->priority(), priority
);
41 queue_
[priority
].push_back(
42 PendingWrite(frame_type
, frame_producer
.release(), stream
));
45 bool SpdyWriteQueue::Dequeue(SpdyFrameType
* frame_type
,
46 scoped_ptr
<SpdyBufferProducer
>* frame_producer
,
47 scoped_refptr
<SpdyStream
>* stream
) {
48 for (int i
= NUM_PRIORITIES
- 1; i
>= 0; --i
) {
49 if (!queue_
[i
].empty()) {
50 PendingWrite pending_write
= queue_
[i
].front();
51 queue_
[i
].pop_front();
52 *frame_type
= pending_write
.frame_type
;
53 frame_producer
->reset(pending_write
.frame_producer
);
54 *stream
= pending_write
.stream
;
61 void SpdyWriteQueue::RemovePendingWritesForStream(
62 const scoped_refptr
<SpdyStream
>& stream
) {
65 // |stream| should not have pending writes in a queue not matching
67 for (int i
= 0; i
< NUM_PRIORITIES
; ++i
) {
68 if (stream
->priority() == i
)
70 for (std::deque
<PendingWrite
>::const_iterator it
= queue_
[i
].begin();
71 it
!= queue_
[i
].end(); ++it
) {
72 DCHECK_NE(it
->stream
, stream
);
77 // Do the actual deletion and removal, preserving FIFO-ness.
78 std::deque
<PendingWrite
>* queue
= &queue_
[stream
->priority()];
79 std::deque
<PendingWrite
>::iterator out_it
= queue
->begin();
80 for (std::deque
<PendingWrite
>::const_iterator it
= queue
->begin();
81 it
!= queue
->end(); ++it
) {
82 if (it
->stream
== stream
) {
83 delete it
->frame_producer
;
89 queue
->erase(out_it
, queue
->end());
92 void SpdyWriteQueue::RemovePendingWritesForStreamsAfter(
93 SpdyStreamId last_good_stream_id
) {
94 for (int i
= 0; i
< NUM_PRIORITIES
; ++i
) {
95 // Do the actual deletion and removal, preserving FIFO-ness.
96 std::deque
<PendingWrite
>* queue
= &queue_
[i
];
97 std::deque
<PendingWrite
>::iterator out_it
= queue
->begin();
98 for (std::deque
<PendingWrite
>::const_iterator it
= queue
->begin();
99 it
!= queue
->end(); ++it
) {
100 if (it
->stream
&& (it
->stream
->stream_id() > last_good_stream_id
||
101 it
->stream
->stream_id() == 0)) {
102 delete it
->frame_producer
;
108 queue
->erase(out_it
, queue
->end());
112 void SpdyWriteQueue::Clear() {
113 for (int i
= 0; i
< NUM_PRIORITIES
; ++i
) {
114 for (std::deque
<PendingWrite
>::iterator it
= queue_
[i
].begin();
115 it
!= queue_
[i
].end(); ++it
) {
116 delete it
->frame_producer
;