Chromium Code Reviews| Index: content/browser/shared_worker/shared_worker_service_impl.cc |
| diff --git a/content/browser/shared_worker/shared_worker_service_impl.cc b/content/browser/shared_worker/shared_worker_service_impl.cc |
| index 8ba7eedf739bbd13e5cc999b0096013aa4a007e1..28840f95b4d9d5c3db60022f5f99773059004ba0 100644 |
| --- a/content/browser/shared_worker/shared_worker_service_impl.cc |
| +++ b/content/browser/shared_worker/shared_worker_service_impl.cc |
| @@ -4,6 +4,12 @@ |
| #include "content/browser/shared_worker/shared_worker_service_impl.h" |
| +#include <algorithm> |
| +#include <iterator> |
| +#include <set> |
| +#include <vector> |
| + |
| +#include "content/browser/renderer_host/render_process_host_impl.h" |
| #include "content/browser/shared_worker/shared_worker_host.h" |
| #include "content/browser/shared_worker/shared_worker_instance.h" |
| #include "content/browser/shared_worker/shared_worker_message_filter.h" |
| @@ -14,16 +20,53 @@ |
| #include "content/public/browser/worker_service_observer.h" |
| namespace content { |
| +namespace { |
| + |
| +void UpdateWorkerDependencyOnUI(const std::vector<int> added_ids, |
| + const std::vector<int> removed_ids) { |
|
kinuko
2014/03/10 04:25:43
nit: const -> const&
horo
2014/03/10 11:48:31
Done.
|
| + for (size_t i = 0; i < added_ids.size(); ++i) { |
| + RenderProcessHostImpl* render_process_host_impl = |
| + static_cast<RenderProcessHostImpl*>( |
| + RenderProcessHost::FromID(added_ids[i])); |
| + if (!render_process_host_impl) |
| + continue; |
| + render_process_host_impl->IncrementWorkerRefCount(); |
| + } |
| + for (size_t i = 0; i < removed_ids.size(); ++i) { |
| + RenderProcessHostImpl* render_process_host_impl = |
| + static_cast<RenderProcessHostImpl*>( |
| + RenderProcessHost::FromID(removed_ids[i])); |
| + if (!render_process_host_impl) |
| + continue; |
| + render_process_host_impl->DecrementWorkerRefCount(); |
| + } |
| +} |
| + |
| +void UpdateWorkerDependency(const std::vector<int> added_ids, |
| + const std::vector<int> removed_ids) { |
| + BrowserThread::PostTask( |
| + BrowserThread::UI, |
| + FROM_HERE, |
| + base::Bind(&UpdateWorkerDependencyOnUI, added_ids, removed_ids)); |
| +} |
| + |
| +} // namespace |
| SharedWorkerServiceImpl* SharedWorkerServiceImpl::GetInstance() { |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| return Singleton<SharedWorkerServiceImpl>::get(); |
| } |
| -SharedWorkerServiceImpl::SharedWorkerServiceImpl() { |
| -} |
| +SharedWorkerServiceImpl::SharedWorkerServiceImpl() |
| + : update_worker_dependency_(UpdateWorkerDependency) {} |
| + |
| +SharedWorkerServiceImpl::~SharedWorkerServiceImpl() {} |
| -SharedWorkerServiceImpl::~SharedWorkerServiceImpl() { |
| +void SharedWorkerServiceImpl::ResetForTesting() { |
| + last_worker_depended_renderers_.clear(); |
| + worker_hosts_.clear(); |
| + observers_.Clear(); |
| + update_worker_dependency_ = UpdateWorkerDependency; |
| } |
| bool SharedWorkerServiceImpl::TerminateWorker(int process_id, int route_id) { |
| @@ -73,6 +116,7 @@ void SharedWorkerServiceImpl::CreateWorker( |
| const WorkerStoragePartition& partition, |
| bool* url_mismatch) { |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| + ScopedWorkerDependencyChecker checker(this); |
| *url_mismatch = false; |
| SharedWorkerInstance* existing_instance = |
| FindSharedWorkerInstance( |
| @@ -135,6 +179,7 @@ void SharedWorkerServiceImpl::ForwardToWorker( |
| void SharedWorkerServiceImpl::DocumentDetached( |
| unsigned long long document_id, |
| SharedWorkerMessageFilter* filter) { |
| + ScopedWorkerDependencyChecker checker(this); |
| for (WorkerHostMap::const_iterator iter = worker_hosts_.begin(); |
| iter != worker_hosts_.end(); |
| ++iter) { |
| @@ -145,6 +190,7 @@ void SharedWorkerServiceImpl::DocumentDetached( |
| void SharedWorkerServiceImpl::WorkerContextClosed( |
| int worker_route_id, |
| SharedWorkerMessageFilter* filter) { |
| + ScopedWorkerDependencyChecker checker(this); |
| if (SharedWorkerHost* host = FindSharedWorkerHost(filter, worker_route_id)) |
| host->WorkerContextClosed(); |
| } |
| @@ -152,6 +198,7 @@ void SharedWorkerServiceImpl::WorkerContextClosed( |
| void SharedWorkerServiceImpl::WorkerContextDestroyed( |
| int worker_route_id, |
| SharedWorkerMessageFilter* filter) { |
| + ScopedWorkerDependencyChecker checker(this); |
| scoped_ptr<SharedWorkerHost> host = |
| worker_hosts_.take_and_erase(std::make_pair(filter->render_process_id(), |
| worker_route_id)); |
| @@ -170,6 +217,7 @@ void SharedWorkerServiceImpl::WorkerScriptLoaded( |
| void SharedWorkerServiceImpl::WorkerScriptLoadFailed( |
| int worker_route_id, |
| SharedWorkerMessageFilter* filter) { |
| + ScopedWorkerDependencyChecker checker(this); |
| scoped_ptr<SharedWorkerHost> host = |
| worker_hosts_.take_and_erase(std::make_pair(filter->render_process_id(), |
| worker_route_id)); |
| @@ -219,6 +267,7 @@ void SharedWorkerServiceImpl::AllowIndexedDB( |
| void SharedWorkerServiceImpl::OnSharedWorkerMessageFilterClosing( |
| SharedWorkerMessageFilter* filter) { |
| + ScopedWorkerDependencyChecker checker(this); |
| std::vector<ProcessRouteIdPair> remove_list; |
| for (WorkerHostMap::iterator iter = worker_hosts_.begin(); |
| iter != worker_hosts_.end(); |
| @@ -253,4 +302,48 @@ SharedWorkerInstance* SharedWorkerServiceImpl::FindSharedWorkerInstance( |
| return NULL; |
| } |
| +const std::set<int> |
| +SharedWorkerServiceImpl::GetRenderersWithWorkerDependency() { |
| + std::set<int> dependend_renderers; |
| + for (WorkerHostMap::iterator host_iter = worker_hosts_.begin(); |
| + host_iter != worker_hosts_.end(); |
| + ++host_iter) { |
| + const int process_id = host_iter->first.first; |
| + if (dependend_renderers.count(process_id)) |
| + continue; |
| + SharedWorkerInstance* instance = host_iter->second->instance(); |
| + if (instance && |
| + instance->worker_document_set()->ContainsExternalRenderer(process_id)) { |
| + dependend_renderers.insert(process_id); |
| + } |
| + } |
| + return dependend_renderers; |
|
kinuko
2014/03/10 04:25:43
nit: probably you meant depended_ or dependent_ ?
horo
2014/03/10 11:48:31
Done.
|
| +} |
| + |
| +void SharedWorkerServiceImpl::CheckWorkerDependency() { |
| + const std::set<int> current_worker_depended_renderers = |
| + GetRenderersWithWorkerDependency(); |
| + std::vector<int> added_items; |
| + std::vector<int> removed_items; |
| + std::set_difference(current_worker_depended_renderers.begin(), |
| + current_worker_depended_renderers.end(), |
| + last_worker_depended_renderers_.begin(), |
| + last_worker_depended_renderers_.end(), |
| + std::back_inserter(added_items)); |
| + std::set_difference(last_worker_depended_renderers_.begin(), |
| + last_worker_depended_renderers_.end(), |
| + current_worker_depended_renderers.begin(), |
| + current_worker_depended_renderers.end(), |
| + std::back_inserter(removed_items)); |
| + if (!added_items.empty() || !removed_items.empty()) { |
| + last_worker_depended_renderers_ = current_worker_depended_renderers; |
| + update_worker_dependency_(added_items, removed_items); |
| + } |
| +} |
| + |
| +void SharedWorkerServiceImpl::ChangeUpdateWorkerDependencyFuncForTesting( |
| + UpdateWorkerDependencyFunc new_func) { |
| + update_worker_dependency_ = new_func; |
| +} |
| + |
| } // namespace content |