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

Side by Side Diff: ipc/ipc_channel_reader.cc

Issue 1377483003: Trim IPC ChannelReader's buffer. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@reserve-buffer
Patch Set: Fix USE_ATTACHMENT_BROKER && defined(OS_MACOSX) && !defined(OS_IOS) case Created 5 years, 1 month 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
« no previous file with comments | « ipc/ipc_channel_reader.h ('k') | ipc/ipc_channel_reader_unittest.cc » ('j') | 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "ipc/ipc_channel_reader.h" 5 #include "ipc/ipc_channel_reader.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "ipc/ipc_listener.h" 9 #include "ipc/ipc_listener.h"
10 #include "ipc/ipc_logging.h" 10 #include "ipc/ipc_logging.h"
11 #include "ipc/ipc_message.h" 11 #include "ipc/ipc_message.h"
12 #include "ipc/ipc_message_attachment_set.h" 12 #include "ipc/ipc_message_attachment_set.h"
13 #include "ipc/ipc_message_macros.h" 13 #include "ipc/ipc_message_macros.h"
14 14
15 namespace IPC { 15 namespace IPC {
16 namespace internal { 16 namespace internal {
17 17
18 ChannelReader::ChannelReader(Listener* listener) : listener_(listener) { 18 ChannelReader::ChannelReader(Listener* listener)
19 : listener_(listener),
20 max_input_buffer_size_(Channel::kMaximumReadBufferSize) {
19 memset(input_buf_, 0, sizeof(input_buf_)); 21 memset(input_buf_, 0, sizeof(input_buf_));
20 } 22 }
21 23
22 ChannelReader::~ChannelReader() { 24 ChannelReader::~ChannelReader() {
23 DCHECK(blocked_ids_.empty()); 25 DCHECK(blocked_ids_.empty());
24 } 26 }
25 27
26 ChannelReader::DispatchState ChannelReader::ProcessIncomingMessages() { 28 ChannelReader::DispatchState ChannelReader::ProcessIncomingMessages() {
27 while (true) { 29 while (true) {
28 int bytes_read = 0; 30 int bytes_read = 0;
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 p = info.message_end; 109 p = info.message_end;
108 } else { 110 } else {
109 // Last message is partial. 111 // Last message is partial.
110 next_message_size = info.message_size; 112 next_message_size = info.message_size;
111 if (!CheckMessageSize(next_message_size)) 113 if (!CheckMessageSize(next_message_size))
112 return false; 114 return false;
113 break; 115 break;
114 } 116 }
115 } 117 }
116 118
119 // Account for the case where last message's byte is in the next data chunk.
120 size_t next_message_buffer_size = next_message_size ?
121 next_message_size + Channel::kReadBufferSize - 1:
122 0;
123
117 // Save any partial data in the overflow buffer. 124 // Save any partial data in the overflow buffer.
118 input_overflow_buf_.assign(p, end - p); 125 input_overflow_buf_.assign(p, end - p);
119 126
120 if (!input_overflow_buf_.empty()) { 127 if (!input_overflow_buf_.empty()) {
121 // We have something in the overflow buffer, which means that we will 128 // We have something in the overflow buffer, which means that we will
122 // append the next data chunk (instead of parsing it directly). So we 129 // append the next data chunk (instead of parsing it directly). So we
123 // resize the buffer to fit the next message, to avoid repeatedly 130 // resize the buffer to fit the next message, to avoid repeatedly
124 // growing the buffer as we receive all message' data chunks. 131 // growing the buffer as we receive all message' data chunks.
125 next_message_size += Channel::kReadBufferSize - 1; 132 if (next_message_buffer_size > input_overflow_buf_.capacity()) {
126 if (next_message_size > input_overflow_buf_.capacity()) { 133 input_overflow_buf_.reserve(next_message_buffer_size);
127 input_overflow_buf_.reserve(next_message_size);
128 } 134 }
129 } 135 }
130 136
137 // Trim the buffer if we can
138 if (next_message_buffer_size < max_input_buffer_size_ &&
139 input_overflow_buf_.size() < max_input_buffer_size_ &&
140 input_overflow_buf_.capacity() > max_input_buffer_size_) {
141 // std::string doesn't really have a method to shrink capacity to
142 // a specific value, so we have to swap with another string.
143 std::string trimmed_buf;
144 trimmed_buf.reserve(max_input_buffer_size_);
145 if (trimmed_buf.capacity() > max_input_buffer_size_) {
146 // Since we don't control how much space reserve() actually reserves,
147 // we have to go other way around and change the max size to avoid
148 // getting into the outer if() again.
149 max_input_buffer_size_ = trimmed_buf.capacity();
150 }
151 trimmed_buf.assign(input_overflow_buf_.data(),
152 input_overflow_buf_.size());
153 input_overflow_buf_.swap(trimmed_buf);
154 }
155
131 if (input_overflow_buf_.empty() && !DidEmptyInputBuffers()) 156 if (input_overflow_buf_.empty() && !DidEmptyInputBuffers())
132 return false; 157 return false;
133 return true; 158 return true;
134 } 159 }
135 160
136 bool ChannelReader::HandleTranslatedMessage( 161 bool ChannelReader::HandleTranslatedMessage(
137 Message* translated_message, 162 Message* translated_message,
138 const AttachmentIdVector& attachment_ids) { 163 const AttachmentIdVector& attachment_ids) {
139 164
140 // Immediately handle internal messages. 165 // Immediately handle internal messages.
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
299 if (size <= Channel::kMaximumMessageSize) { 324 if (size <= Channel::kMaximumMessageSize) {
300 return true; 325 return true;
301 } 326 }
302 input_overflow_buf_.clear(); 327 input_overflow_buf_.clear();
303 LOG(ERROR) << "IPC message is too big: " << size; 328 LOG(ERROR) << "IPC message is too big: " << size;
304 return false; 329 return false;
305 } 330 }
306 331
307 } // namespace internal 332 } // namespace internal
308 } // namespace IPC 333 } // namespace IPC
OLDNEW
« no previous file with comments | « ipc/ipc_channel_reader.h ('k') | ipc/ipc_channel_reader_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698