- add sources.
[platform/framework/web/crosswalk.git] / src / net / spdy / spdy_write_queue.cc
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.
4
5 #include "net/spdy/spdy_write_queue.h"
6
7 #include <cstddef>
8
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"
13
14 namespace net {
15
16 SpdyWriteQueue::PendingWrite::PendingWrite() : frame_producer(NULL) {}
17
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),
24       stream(stream),
25       has_stream(stream.get() != NULL) {}
26
27 SpdyWriteQueue::PendingWrite::~PendingWrite() {}
28
29 SpdyWriteQueue::SpdyWriteQueue() {}
30
31 SpdyWriteQueue::~SpdyWriteQueue() {
32   Clear();
33 }
34
35 bool SpdyWriteQueue::IsEmpty() const {
36   for (int i = MINIMUM_PRIORITY; i <= MAXIMUM_PRIORITY; i++) {
37     if (!queue_[i].empty())
38       return false;
39   }
40   return true;
41 }
42
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);
49   if (stream.get())
50     DCHECK_EQ(stream->priority(), priority);
51   queue_[priority].push_back(
52       PendingWrite(frame_type, frame_producer.release(), stream));
53 }
54
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());
67       return true;
68     }
69   }
70   return false;
71 }
72
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);
78
79   DCHECK(stream.get());
80   if (DCHECK_IS_ON()) {
81     // |stream| should not have pending writes in a queue not matching
82     // its priority.
83     for (int i = MINIMUM_PRIORITY; i <= MAXIMUM_PRIORITY; ++i) {
84       if (priority == i)
85         continue;
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());
89       }
90     }
91   }
92
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;
100     } else {
101       *out_it = *it;
102       ++out_it;
103     }
104   }
105   queue->erase(out_it, queue->end());
106 }
107
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;
119       } else {
120         *out_it = *it;
121         ++out_it;
122       }
123     }
124     queue->erase(out_it, queue->end());
125   }
126 }
127
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;
133     }
134     queue_[i].clear();
135   }
136 }
137
138 }  // namespace net