Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Side by Side Diff: net/spdy/spdy_write_queue.cc

Issue 265093004: SPDY: Add a bunch of CHECKs into SpdyWriteQueue to detect re-entrancy. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add more removing_writes_. Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/spdy/spdy_write_queue.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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_);
137 removing_writes_ = true;
129 for (int i = MINIMUM_PRIORITY; i <= MAXIMUM_PRIORITY; ++i) { 138 for (int i = MINIMUM_PRIORITY; i <= MAXIMUM_PRIORITY; ++i) {
130 for (std::deque<PendingWrite>::iterator it = queue_[i].begin(); 139 for (std::deque<PendingWrite>::iterator it = queue_[i].begin();
131 it != queue_[i].end(); ++it) { 140 it != queue_[i].end(); ++it) {
132 delete it->frame_producer; 141 delete it->frame_producer;
133 } 142 }
134 queue_[i].clear(); 143 queue_[i].clear();
135 } 144 }
145 removing_writes_ = false;
136 } 146 }
137 147
138 } // namespace net 148 } // namespace net
OLDNEW
« no previous file with comments | « net/spdy/spdy_write_queue.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698