Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 |
| OLD | NEW |