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

Side by Side Diff: content/child/threaded_data_provider.cc

Issue 689713004: Threaded data provider: Support main thread data notifications (Chrome side) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 5 years, 11 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "content/child/threaded_data_provider.h" 5 #include "content/child/threaded_data_provider.h"
6 6
7 #include "content/child/child_process.h" 7 #include "content/child/child_process.h"
8 #include "content/child/child_thread.h" 8 #include "content/child/child_thread.h"
9 #include "content/child/resource_dispatcher.h" 9 #include "content/child/resource_dispatcher.h"
10 #include "content/child/thread_safe_sender.h" 10 #include "content/child/thread_safe_sender.h"
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 // When this happens, the provider should no longer be called on the 199 // When this happens, the provider should no longer be called on the
200 // background thread as it's about to be destroyed on the main thread. 200 // background thread as it's about to be destroyed on the main thread.
201 // Destructing the weak pointer factory means invalidating the weak pointers 201 // Destructing the weak pointer factory means invalidating the weak pointers
202 // which means no callbacks from the filter will happen and nothing else will 202 // which means no callbacks from the filter will happen and nothing else will
203 // use this instance on the background thread. 203 // use this instance on the background thread.
204 background_thread_weak_factory_.reset(NULL); 204 background_thread_weak_factory_.reset(NULL);
205 main_thread_task_runner_->PostTask(FROM_HERE, 205 main_thread_task_runner_->PostTask(FROM_HERE,
206 base::Bind(&DestructOnMainThread, this)); 206 base::Bind(&DestructOnMainThread, this));
207 } 207 }
208 208
209 void ThreadedDataProvider::OnRequestCompleteForegroundThread(
210 base::WeakPtr<ResourceDispatcher> resource_dispatcher,
211 const ResourceMsg_RequestCompleteData& request_complete_data,
212 const base::TimeTicks& renderer_completion_time) {
213 DCHECK(ChildThread::current());
214
215 background_thread_.message_loop()->PostTask(FROM_HERE,
216 base::Bind(&ThreadedDataProvider::OnRequestCompleteBackgroundThread,
217 base::Unretained(this), resource_dispatcher,
218 request_complete_data, renderer_completion_time));
219 }
220
221 void ThreadedDataProvider::OnRequestCompleteBackgroundThread(
222 base::WeakPtr<ResourceDispatcher> resource_dispatcher,
223 const ResourceMsg_RequestCompleteData& request_complete_data,
224 const base::TimeTicks& renderer_completion_time) {
225 DCHECK(background_thread_.isCurrentThread());
226
227 main_thread_task_runner_->PostTask(FROM_HERE,
228 base::Bind(
229 &ResourceDispatcher::CompletedRequestAfterBackgroundThreadFlush,
230 resource_dispatcher,
231 request_id_,
232 request_complete_data,
233 renderer_completion_time));
234 }
235
209 void ThreadedDataProvider::OnResourceMessageFilterAddedMainThread() { 236 void ThreadedDataProvider::OnResourceMessageFilterAddedMainThread() {
210 DCHECK(ChildThread::current()); 237 DCHECK(ChildThread::current());
211 DCHECK(background_thread_weak_factory_); 238 DCHECK(background_thread_weak_factory_);
212 239
213 // We bounce this message from the I/O thread via the main thread and then 240 // We bounce this message from the I/O thread via the main thread and then
214 // to our background thread, following the same path as incoming data before 241 // to our background thread, following the same path as incoming data before
215 // our filter gets added, to make sure there's nothing still incoming. 242 // our filter gets added, to make sure there's nothing still incoming.
216 background_thread_.message_loop()->PostTask(FROM_HERE, 243 background_thread_.message_loop()->PostTask(FROM_HERE,
217 base::Bind( 244 base::Bind(
218 &ThreadedDataProvider::OnResourceMessageFilterAddedBackgroundThread, 245 &ThreadedDataProvider::OnResourceMessageFilterAddedBackgroundThread,
219 background_thread_weak_factory_->GetWeakPtr())); 246 background_thread_weak_factory_->GetWeakPtr()));
220 } 247 }
221 248
222 void ThreadedDataProvider::OnResourceMessageFilterAddedBackgroundThread() { 249 void ThreadedDataProvider::OnResourceMessageFilterAddedBackgroundThread() {
223 DCHECK(background_thread_.isCurrentThread()); 250 DCHECK(background_thread_.isCurrentThread());
224 resource_filter_active_ = true; 251 resource_filter_active_ = true;
225 252
226 // At this point we know no more data is going to arrive from the main thread, 253 // At this point we know no more data is going to arrive from the main thread,
227 // so we can process any data we've received directly from the I/O thread 254 // so we can process any data we've received directly from the I/O thread
228 // in the meantime. 255 // in the meantime.
229 if (!queued_data_.empty()) { 256 if (!queued_data_.empty()) {
230 std::vector<QueuedSharedMemoryData>::iterator iter = queued_data_.begin(); 257 std::vector<QueuedSharedMemoryData>::iterator iter = queued_data_.begin();
231 for (; iter != queued_data_.end(); ++iter) { 258 for (; iter != queued_data_.end(); ++iter) {
232 ForwardAndACKData(iter->data, iter->length); 259 ForwardAndACKData(iter->data, iter->length, iter->encoded_length);
233 } 260 }
234 261
235 queued_data_.clear(); 262 queued_data_.clear();
236 } 263 }
237 } 264 }
238 265
239 void ThreadedDataProvider::OnReceivedDataOnBackgroundThread( 266 void ThreadedDataProvider::OnReceivedDataOnBackgroundThread(
240 int data_offset, int data_length, int encoded_data_length) { 267 int data_offset, int data_length, int encoded_data_length) {
241 DCHECK(background_thread_.isCurrentThread()); 268 DCHECK(background_thread_.isCurrentThread());
242 DCHECK(shm_buffer_ != NULL); 269 DCHECK(shm_buffer_ != NULL);
243 270
244 CHECK_GE(shm_size_, data_offset + data_length); 271 CHECK_GE(shm_size_, data_offset + data_length);
245 const char* data_ptr = static_cast<char*>(shm_buffer_->memory()); 272 const char* data_ptr = static_cast<char*>(shm_buffer_->memory());
246 CHECK(data_ptr); 273 CHECK(data_ptr);
247 CHECK(data_ptr + data_offset); 274 CHECK(data_ptr + data_offset);
248 275
249 if (resource_filter_active_) { 276 if (resource_filter_active_) {
250 ForwardAndACKData(data_ptr + data_offset, data_length); 277 ForwardAndACKData(data_ptr + data_offset, data_length, encoded_data_length);
251 } else { 278 } else {
252 // There's a brief interval between the point where we know the filter 279 // There's a brief interval between the point where we know the filter
253 // has been installed on the I/O thread, and when we know for sure there's 280 // has been installed on the I/O thread, and when we know for sure there's
254 // no more data coming in from the main thread (from before the filter 281 // no more data coming in from the main thread (from before the filter
255 // got added). If we get any data during that interval, we need to queue 282 // got added). If we get any data during that interval, we need to queue
256 // it until we're certain we've processed all the main thread data to make 283 // it until we're certain we've processed all the main thread data to make
257 // sure we forward (and ACK) everything in the right order. 284 // sure we forward (and ACK) everything in the right order.
258 QueuedSharedMemoryData queued_data; 285 QueuedSharedMemoryData queued_data;
259 queued_data.data = data_ptr + data_offset; 286 queued_data.data = data_ptr + data_offset;
260 queued_data.length = data_length; 287 queued_data.length = data_length;
288 queued_data.encoded_length = encoded_data_length;
261 queued_data_.push_back(queued_data); 289 queued_data_.push_back(queued_data);
262 } 290 }
263 } 291 }
264 292
265 void ThreadedDataProvider::OnReceivedDataOnForegroundThread( 293 void ThreadedDataProvider::OnReceivedDataOnForegroundThread(
266 const char* data, int data_length, int encoded_data_length) { 294 const char* data, int data_length, int encoded_data_length) {
267 DCHECK(ChildThread::current()); 295 DCHECK(ChildThread::current());
268 296
269 background_thread_.message_loop()->PostTask(FROM_HERE, 297 background_thread_.message_loop()->PostTask(FROM_HERE,
270 base::Bind(&ThreadedDataProvider::ForwardAndACKData, 298 base::Bind(&ThreadedDataProvider::ForwardAndACKData,
271 base::Unretained(this), 299 base::Unretained(this),
272 data, data_length)); 300 data, data_length, encoded_data_length));
273 } 301 }
274 302
275 void ThreadedDataProvider::ForwardAndACKData(const char* data, 303 void ThreadedDataProvider::ForwardAndACKData(const char* data,
276 int data_length) { 304 int data_length,
305 int encoded_data_length) {
277 DCHECK(background_thread_.isCurrentThread()); 306 DCHECK(background_thread_.isCurrentThread());
278 307
279 // TODO(oysteine): SiteIsolationPolicy needs to be be checked 308 // TODO(oysteine): SiteIsolationPolicy needs to be be checked
280 // here before we pass the data to the data provider 309 // here before we pass the data to the data provider
281 // (or earlier on the I/O thread), otherwise once SiteIsolationPolicy does 310 // (or earlier on the I/O thread), otherwise once SiteIsolationPolicy does
282 // actual blocking as opposed to just UMA logging this will bypass it. 311 // actual blocking as opposed to just UMA logging this will bypass it.
283 threaded_data_receiver_->acceptData(data, data_length); 312 threaded_data_receiver_->acceptData(data, data_length);
313
314 scoped_ptr<std::vector<char> > data_copy;
315 if (threaded_data_receiver_->needsMainthreadDataCopy()) {
davidben 2015/01/23 19:46:43 Can needsMainthreadDataCopy be called on both thre
oystein (OOO til 10th of July) 2015/01/23 21:23:47 Yep, it's threadsafe.
316 data_copy.reset(new std::vector<char>(data_length));
317 memcpy(data_copy->data(), data, data_length);
318 }
319
320 main_thread_task_runner_->PostTask(FROM_HERE,
321 base::Bind(&ThreadedDataProvider::DataNotifyForegroundThread,
322 base::Unretained(this),
323 base::Passed(&data_copy),
324 data_length,
325 encoded_data_length));
326
284 ipc_channel_->Send(new ResourceHostMsg_DataReceived_ACK(request_id_)); 327 ipc_channel_->Send(new ResourceHostMsg_DataReceived_ACK(request_id_));
285 } 328 }
286 329
330 void ThreadedDataProvider::DataNotifyForegroundThread(
331 scoped_ptr<std::vector<char> > data_copy,
332 int data_length,
333 int encoded_data_length) {
334 DCHECK(!data_copy || threaded_data_receiver_->needsMainthreadDataCopy());
davidben 2015/01/23 19:46:43 Nit: I'd maybe also DCHECK something like if (data
oystein (OOO til 10th of July) 2015/01/23 21:23:47 Done.
335
336 threaded_data_receiver_->acceptMainthreadDataNotification(
337 data_copy ? data_copy->data() : NULL, data_length, encoded_data_length);
davidben 2015/01/23 19:46:43 std::vector::data is a C++11-ism. I don't think al
oystein (OOO til 10th of July) 2015/01/23 21:23:47 Done.
338 }
339
287 } // namespace content 340 } // namespace content
OLDNEW
« content/child/resource_dispatcher.cc ('K') | « content/child/threaded_data_provider.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698