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 |