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 d5a06b36a8a2a691c1ae363c28783c3452e832ef..47a32c86e811cde8aeefe5bd8812a9af8b7c7501 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,6 +20,29 @@ |
#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) { |
+ 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(); |
+ } |
+} |
+ |
+} // namespace |
SharedWorkerServiceImpl* SharedWorkerServiceImpl::GetInstance() { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
@@ -55,6 +84,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( |
@@ -117,6 +147,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) { |
@@ -127,6 +158,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(); |
} |
@@ -134,6 +166,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)); |
@@ -152,6 +185,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)); |
@@ -201,6 +235,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(); |
@@ -235,4 +270,45 @@ SharedWorkerInstance* SharedWorkerServiceImpl::FindSharedWorkerInstance( |
return NULL; |
} |
+const std::set<int> SharedWorkerServiceImpl::GetWorkerDependedRenderers() { |
+ 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; |
+} |
+ |
+void SharedWorkerServiceImpl::CheckWorkerDependency() { |
+ const std::set<int> current_worker_depended_renderers = |
+ GetWorkerDependedRenderers(); |
+ 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; |
+ BrowserThread::PostTask( |
+ BrowserThread::UI, |
+ FROM_HERE, |
+ base::Bind(&UpdateWorkerDependencyOnUI, added_items, removed_items)); |
+ } |
+} |
+ |
} // namespace content |