Index: content/child/threaded_data_provider.cc |
diff --git a/content/child/threaded_data_provider.cc b/content/child/threaded_data_provider.cc |
index 69ed34b0795dc5854cf9295621ebd0759c0cc826..6a533d35f81010a488a34aa92d5436f2a1d23551 100644 |
--- a/content/child/threaded_data_provider.cc |
+++ b/content/child/threaded_data_provider.cc |
@@ -157,13 +157,13 @@ ThreadedDataProvider::~ThreadedDataProvider() { |
delete threaded_data_receiver_; |
} |
-void DestructOnMainThread(ThreadedDataProvider* data_provider) { |
+void ThreadedDataProvider::DestructOnMainThread() { |
DCHECK(ChildThreadImpl::current()); |
// The ThreadedDataProvider must be destructed on the main thread to |
// be threadsafe when removing the message filter and releasing the shared |
// memory buffer. |
- delete data_provider; |
+ delete this; |
} |
void ThreadedDataProvider::Stop() { |
@@ -203,7 +203,35 @@ void ThreadedDataProvider::StopOnBackgroundThread() { |
// use this instance on the background thread. |
background_thread_weak_factory_.reset(NULL); |
main_thread_task_runner_->PostTask(FROM_HERE, |
- base::Bind(&DestructOnMainThread, this)); |
+ base::Bind(&ThreadedDataProvider::DestructOnMainThread, |
+ base::Unretained(this))); |
+} |
+ |
+void ThreadedDataProvider::OnRequestCompleteForegroundThread( |
+ base::WeakPtr<ResourceDispatcher> resource_dispatcher, |
+ const ResourceMsg_RequestCompleteData& request_complete_data, |
+ const base::TimeTicks& renderer_completion_time) { |
+ DCHECK(ChildThreadImpl::current()); |
+ |
+ background_thread_.message_loop()->PostTask(FROM_HERE, |
+ base::Bind(&ThreadedDataProvider::OnRequestCompleteBackgroundThread, |
+ base::Unretained(this), resource_dispatcher, |
+ request_complete_data, renderer_completion_time)); |
+} |
+ |
+void ThreadedDataProvider::OnRequestCompleteBackgroundThread( |
+ base::WeakPtr<ResourceDispatcher> resource_dispatcher, |
+ const ResourceMsg_RequestCompleteData& request_complete_data, |
+ const base::TimeTicks& renderer_completion_time) { |
+ DCHECK(background_thread_.isCurrentThread()); |
+ |
+ main_thread_task_runner_->PostTask(FROM_HERE, |
+ base::Bind( |
+ &ResourceDispatcher::CompletedRequestAfterBackgroundThreadFlush, |
+ resource_dispatcher, |
+ request_id_, |
+ request_complete_data, |
+ renderer_completion_time)); |
} |
void ThreadedDataProvider::OnResourceMessageFilterAddedMainThread() { |
@@ -229,7 +257,7 @@ void ThreadedDataProvider::OnResourceMessageFilterAddedBackgroundThread() { |
if (!queued_data_.empty()) { |
std::vector<QueuedSharedMemoryData>::iterator iter = queued_data_.begin(); |
for (; iter != queued_data_.end(); ++iter) { |
- ForwardAndACKData(iter->data, iter->length); |
+ ForwardAndACKData(iter->data, iter->length, iter->encoded_length); |
} |
queued_data_.clear(); |
@@ -247,7 +275,7 @@ void ThreadedDataProvider::OnReceivedDataOnBackgroundThread( |
CHECK(data_ptr + data_offset); |
if (resource_filter_active_) { |
- ForwardAndACKData(data_ptr + data_offset, data_length); |
+ ForwardAndACKData(data_ptr + data_offset, data_length, encoded_data_length); |
} else { |
// There's a brief interval between the point where we know the filter |
// has been installed on the I/O thread, and when we know for sure there's |
@@ -258,6 +286,7 @@ void ThreadedDataProvider::OnReceivedDataOnBackgroundThread( |
QueuedSharedMemoryData queued_data; |
queued_data.data = data_ptr + data_offset; |
queued_data.length = data_length; |
+ queued_data.encoded_length = encoded_data_length; |
queued_data_.push_back(queued_data); |
} |
} |
@@ -269,11 +298,12 @@ void ThreadedDataProvider::OnReceivedDataOnForegroundThread( |
background_thread_.message_loop()->PostTask(FROM_HERE, |
base::Bind(&ThreadedDataProvider::ForwardAndACKData, |
base::Unretained(this), |
- data, data_length)); |
+ data, data_length, encoded_data_length)); |
} |
void ThreadedDataProvider::ForwardAndACKData(const char* data, |
- int data_length) { |
+ int data_length, |
+ int encoded_data_length) { |
DCHECK(background_thread_.isCurrentThread()); |
// TODO(oysteine): SiteIsolationPolicy needs to be be checked |
@@ -281,7 +311,34 @@ void ThreadedDataProvider::ForwardAndACKData(const char* data, |
// (or earlier on the I/O thread), otherwise once SiteIsolationPolicy does |
// actual blocking as opposed to just UMA logging this will bypass it. |
threaded_data_receiver_->acceptData(data, data_length); |
+ |
+ scoped_ptr<std::vector<char>> data_copy; |
+ if (threaded_data_receiver_->needsMainthreadDataCopy()) { |
+ data_copy.reset(new std::vector<char>(data, data + data_length)); |
+ } |
+ |
+ main_thread_task_runner_->PostTask(FROM_HERE, |
+ base::Bind(&ThreadedDataProvider::DataNotifyForegroundThread, |
+ base::Unretained(this), |
+ base::Passed(&data_copy), |
+ data_length, |
+ encoded_data_length)); |
+ |
ipc_channel_->Send(new ResourceHostMsg_DataReceived_ACK(request_id_)); |
} |
+void ThreadedDataProvider::DataNotifyForegroundThread( |
+ scoped_ptr<std::vector<char> > data_copy, |
+ int data_length, |
+ int encoded_data_length) { |
+ if (data_copy) { |
+ DCHECK(threaded_data_receiver_->needsMainthreadDataCopy()); |
+ DCHECK_EQ((size_t)data_length, data_copy->size()); |
+ } |
+ |
+ threaded_data_receiver_->acceptMainthreadDataNotification( |
+ (data_copy && !data_copy->empty()) ? &data_copy->front() : NULL, |
+ data_length, encoded_data_length); |
+} |
+ |
} // namespace content |