Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(298)

Unified Diff: content/browser/worker_host/worker_service_impl.cc

Issue 14137016: Lower the priority of shared workers (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Moved visible check into worker_service_impl. Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/browser/worker_host/worker_service_impl.cc
diff --git a/content/browser/worker_host/worker_service_impl.cc b/content/browser/worker_host/worker_service_impl.cc
index 703b31f02ce3b7f2df5423c95c9c37b528c1a923..6c8ce8bd87d6299cbdbb4f32c7ace80ce51a90e3 100644
--- a/content/browser/worker_host/worker_service_impl.cc
+++ b/content/browser/worker_host/worker_service_impl.cc
@@ -10,12 +10,20 @@
#include "base/logging.h"
#include "base/threading/thread.h"
#include "content/browser/devtools/worker_devtools_manager.h"
+#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/worker_host/worker_message_filter.h"
#include "content/browser/worker_host/worker_process_host.h"
#include "content/common/view_messages.h"
#include "content/common/worker_messages.h"
#include "content/public/browser/child_process_data.h"
+#include "content/public/browser/notification_service.h"
+#include "content/public/browser/notification_types.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/render_view_host.h"
+#include "content/public/browser/render_widget_host.h"
+#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/resource_context.h"
+#include "content/public/browser/web_contents.h"
#include "content/public/browser/worker_service_observer.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/process_type.h"
@@ -34,7 +42,12 @@ WorkerServiceImpl* WorkerServiceImpl::GetInstance() {
return Singleton<WorkerServiceImpl>::get();
}
-WorkerServiceImpl::WorkerServiceImpl() : next_worker_route_id_(0) {
+WorkerServiceImpl::WorkerServiceImpl()
+ : next_worker_route_id_(0) {
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&WorkerServiceImpl::RegisterObserver,
+ base::Unretained(this)));
}
WorkerServiceImpl::~WorkerServiceImpl() {
@@ -457,6 +470,10 @@ void WorkerServiceImpl::NotifyWorkerDestroyed(
WorkerDestroyed(process->GetData().id, worker_route_id));
}
+void WorkerServiceImpl::NotifyWorkerProcessCreated() {
+ PostTaskToGatherAndUpdateWorkerPriorities();
+}
+
WorkerProcessHost::WorkerInstance* WorkerServiceImpl::FindSharedWorkerInstance(
const GURL& url,
const string16& name,
@@ -526,4 +543,126 @@ WorkerProcessHost::WorkerInstance* WorkerServiceImpl::CreatePendingInstance(
return &pending_shared_workers_.back();
}
+void WorkerServiceImpl::RegisterObserver() {
jam 2013/05/09 18:02:57 this class is currently completely on the IO threa
shatch 2013/05/09 22:42:49 Done.
+ registrar_.Add(this, content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED,
jam 2013/05/09 18:02:57 nit: likewise, here and below remove the "content:
shatch 2013/05/09 22:42:49 Done.
+ content::NotificationService::AllBrowserContextsAndSources());
+ registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CREATED,
+ content::NotificationService::AllBrowserContextsAndSources());
+}
+
+void WorkerServiceImpl::UpdateWorkerPrioritiesFromVisibleSet(
+ const std::set<std::pair<int, int> >* visible_renderer_ids) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) {
+ if (!iter->IsProcessLaunched())
+ continue;
+ bool throttle = true;
+
+ for (WorkerProcessHost::Instances::const_iterator instance =
+ iter->instances().begin(); instance != iter->instances().end();
+ ++instance) {
+
+ // This code assumes one worker per process
+ WorkerProcessHost::Instances::const_iterator first_instance =
+ iter->instances().begin();
+ if (first_instance == iter->instances().end())
+ continue;
+
+ WorkerDocumentSet::DocumentInfoSet::const_iterator info =
+ first_instance->worker_document_set()->documents().begin();
+
+ for (; info != first_instance->worker_document_set()->documents().end();
+ ++info) {
+ std::pair<int, int> id(
+ info->render_process_id(), info->render_view_id());
+ if (visible_renderer_ids->find(id) != visible_renderer_ids->end()) {
+ throttle = false;
+ break;
+ }
+ }
+
+ if (!throttle ) {
+ break;
+ }
+ }
+
+ iter->SetBackgrounded(throttle);
+ }
+}
+
+void WorkerServiceImpl::OnRenderWidgetVisibilityChanged(
+ std::pair<int, int> id) {
+ std::set<std::pair<int, int> > visible_renderer_ids;
+
+ visible_renderer_ids.insert(id);
+
+ UpdateWorkerPrioritiesFromVisibleSet(&visible_renderer_ids);
+}
+
+void WorkerServiceImpl::GatherVisibleIDsAndUpdateWorkerPriorities() {
+ std::set<std::pair<int, int> >* visible_renderer_ids =
+ new std::set<std::pair<int, int> >();
+
+ // Gather up all the visible renderer process/view pairs
+ for (content::RenderProcessHost::iterator it =
+ content::RenderProcessHost::AllHostsIterator();
darin (slow to review) 2013/05/10 23:42:13 nit: like function calls, we usually wrap the line
shatch 2013/05/13 17:47:47 Done.
+ !it.IsAtEnd(); it.Advance()) {
+ content::RenderProcessHost* host = it.GetCurrentValue();
+ if (host->VisibleWidgetCount()) {
+ for (content::RenderProcessHost::RenderWidgetHostsIterator rit =
+ host->GetRenderWidgetHostsIterator(); !rit.IsAtEnd(); rit.Advance()) {
+ content::RenderWidgetHost* widget = host->GetRenderWidgetHostByID(
+ rit.GetCurrentKey());
+ if (widget) {
+ content::RenderWidgetHostView* view = widget->GetView();
+ if (view && view->IsShowing()) {
+ visible_renderer_ids->insert(
+ std::pair<int, int>(host->GetID(),
+ widget->GetRoutingID()));
+ }
+ }
+ }
+ }
+ }
+
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&WorkerServiceImpl::UpdateWorkerPrioritiesFromVisibleSet,
+ base::Unretained(this),
+ base::Owned(visible_renderer_ids)));
+}
+
+void WorkerServiceImpl::PostTaskToGatherAndUpdateWorkerPriorities() {
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(
+ &WorkerServiceImpl::GatherVisibleIDsAndUpdateWorkerPriorities,
+ base::Unretained(this)));
+}
+
+void WorkerServiceImpl::Observe(int type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ if (type == content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED) {
+ bool visible = *content::Details<bool>(details).ptr();
+
+ if (visible) {
+ int id = content::Source<content::RenderWidgetHost>(source).ptr()->
jam 2013/05/09 18:02:57 nit: naming wise, convention is render_view_id ren
shatch 2013/05/09 22:42:49 Done.
+ GetRoutingID();
+ int pid = content::Source<content::RenderWidgetHost>(source).ptr()->
+ GetProcess()->GetID();
+
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&WorkerServiceImpl::OnRenderWidgetVisibilityChanged,
+ base::Unretained(this),
+ std::pair<int, int>(pid, id)));
+ }
+ }
+ else if (type == NOTIFICATION_RENDERER_PROCESS_CREATED) {
+ PostTaskToGatherAndUpdateWorkerPriorities();
+ }
+}
+
} // namespace content

Powered by Google App Engine
This is Rietveld 408576698