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

Side by Side Diff: trunk/src/content/browser/worker_host/worker_service_impl.cc

Issue 15012025: Revert 199840 "Lower the priority of shared workers that aren't ..." (Closed) Base URL: svn://svn.chromium.org/chrome/
Patch Set: Created 7 years, 7 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « trunk/src/content/browser/worker_host/worker_service_impl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/browser/worker_host/worker_service_impl.h" 5 #include "content/browser/worker_host/worker_service_impl.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/threading/thread.h" 11 #include "base/threading/thread.h"
12 #include "content/browser/devtools/worker_devtools_manager.h" 12 #include "content/browser/devtools/worker_devtools_manager.h"
13 #include "content/browser/renderer_host/render_widget_host_impl.h"
14 #include "content/browser/worker_host/worker_message_filter.h" 13 #include "content/browser/worker_host/worker_message_filter.h"
15 #include "content/browser/worker_host/worker_process_host.h" 14 #include "content/browser/worker_host/worker_process_host.h"
16 #include "content/common/view_messages.h" 15 #include "content/common/view_messages.h"
17 #include "content/common/worker_messages.h" 16 #include "content/common/worker_messages.h"
18 #include "content/public/browser/child_process_data.h" 17 #include "content/public/browser/child_process_data.h"
19 #include "content/public/browser/notification_service.h"
20 #include "content/public/browser/notification_types.h"
21 #include "content/public/browser/render_process_host.h"
22 #include "content/public/browser/render_view_host.h"
23 #include "content/public/browser/render_widget_host.h"
24 #include "content/public/browser/render_widget_host_view.h"
25 #include "content/public/browser/resource_context.h" 18 #include "content/public/browser/resource_context.h"
26 #include "content/public/browser/web_contents.h"
27 #include "content/public/browser/worker_service_observer.h" 19 #include "content/public/browser/worker_service_observer.h"
28 #include "content/public/common/content_switches.h" 20 #include "content/public/common/content_switches.h"
29 #include "content/public/common/process_type.h" 21 #include "content/public/common/process_type.h"
30 22
31 namespace content { 23 namespace content {
32 24
33 const int WorkerServiceImpl::kMaxWorkersWhenSeparate = 64; 25 const int WorkerServiceImpl::kMaxWorkersWhenSeparate = 64;
34 const int WorkerServiceImpl::kMaxWorkersPerTabWhenSeparate = 16; 26 const int WorkerServiceImpl::kMaxWorkersPerTabWhenSeparate = 16;
35 27
36 class WorkerPrioritySetter
37 : public NotificationObserver,
38 public base::RefCountedThreadSafe<WorkerPrioritySetter,
39 BrowserThread::DeleteOnUIThread> {
40 public:
41 WorkerPrioritySetter();
42
43 // Invoked by WorkerServiceImpl when a worker process is created.
44 void NotifyWorkerProcessCreated();
45
46 private:
47 friend class base::RefCountedThreadSafe<WorkerPrioritySetter>;
48 friend struct BrowserThread::DeleteOnThread<BrowserThread::UI>;
49 friend class base::DeleteHelper<WorkerPrioritySetter>;
50 virtual ~WorkerPrioritySetter();
51
52 // Posts a task to perform a worker priority update.
53 void PostTaskToGatherAndUpdateWorkerPriorities();
54
55 // Gathers up a list of the visible tabs and then updates priorities for
56 // all the shared workers.
57 void GatherVisibleIDsAndUpdateWorkerPriorities();
58
59 // Registers as an observer to receive notifications about
60 // widgets being shown.
61 void RegisterObserver();
62
63 // Sets priorities for shared workers given a set of visible tabs (as a
64 // std::set of std::pair<render_process, render_view> ids.
65 void UpdateWorkerPrioritiesFromVisibleSet(
66 const std::set<std::pair<int, int> >* visible);
67
68 // Called to refresh worker priorities when focus changes between tabs.
69 void OnRenderWidgetVisibilityChanged(std::pair<int, int>);
70
71 // NotificationObserver implementation.
72 virtual void Observe(int type,
73 const NotificationSource& source,
74 const NotificationDetails& details) OVERRIDE;
75
76 NotificationRegistrar registrar_;
77 };
78
79 WorkerPrioritySetter::WorkerPrioritySetter() {
80 BrowserThread::PostTask(
81 BrowserThread::UI, FROM_HERE,
82 base::Bind(&WorkerPrioritySetter::RegisterObserver, this));
83 }
84
85 WorkerPrioritySetter::~WorkerPrioritySetter() {
86 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
87 }
88
89 void WorkerPrioritySetter::NotifyWorkerProcessCreated() {
90 PostTaskToGatherAndUpdateWorkerPriorities();
91 }
92
93 void WorkerPrioritySetter::PostTaskToGatherAndUpdateWorkerPriorities() {
94 BrowserThread::PostTask(
95 BrowserThread::UI, FROM_HERE,
96 base::Bind(
97 &WorkerPrioritySetter::GatherVisibleIDsAndUpdateWorkerPriorities,
98 this));
99 }
100
101 void WorkerPrioritySetter::GatherVisibleIDsAndUpdateWorkerPriorities() {
102 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
103 std::set<std::pair<int, int> >* visible_renderer_ids =
104 new std::set<std::pair<int, int> >();
105
106 // Gather up all the visible renderer process/view pairs
107 for (RenderProcessHost::iterator it =
108 RenderProcessHost::AllHostsIterator();
109 !it.IsAtEnd(); it.Advance()) {
110 RenderProcessHost* render_process_host = it.GetCurrentValue();
111 if (render_process_host->VisibleWidgetCount()) {
112 for (RenderProcessHost::RenderWidgetHostsIterator rit =
113 render_process_host->GetRenderWidgetHostsIterator(); !rit.IsAtEnd();
114 rit.Advance()) {
115 RenderWidgetHost* render_widget =
116 render_process_host->GetRenderWidgetHostByID(rit.GetCurrentKey());
117 if (render_widget) {
118 RenderWidgetHostView* render_view = render_widget->GetView();
119 if (render_view && render_view->IsShowing()) {
120 visible_renderer_ids->insert(
121 std::pair<int, int>(render_process_host->GetID(),
122 render_widget->GetRoutingID()));
123 }
124 }
125 }
126 }
127 }
128
129 BrowserThread::PostTask(
130 BrowserThread::IO, FROM_HERE,
131 base::Bind(&WorkerPrioritySetter::UpdateWorkerPrioritiesFromVisibleSet,
132 this, base::Owned(visible_renderer_ids)));
133 }
134
135 void WorkerPrioritySetter::UpdateWorkerPrioritiesFromVisibleSet(
136 const std::set<std::pair<int, int> >* visible_renderer_ids) {
137 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
138
139 for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) {
140 if (!iter->process_launched())
141 continue;
142 bool throttle = true;
143
144 for (WorkerProcessHost::Instances::const_iterator instance =
145 iter->instances().begin(); instance != iter->instances().end();
146 ++instance) {
147
148 // This code assumes one worker per process
149 WorkerProcessHost::Instances::const_iterator first_instance =
150 iter->instances().begin();
151 if (first_instance == iter->instances().end())
152 continue;
153
154 WorkerDocumentSet::DocumentInfoSet::const_iterator info =
155 first_instance->worker_document_set()->documents().begin();
156
157 for (; info != first_instance->worker_document_set()->documents().end();
158 ++info) {
159 std::pair<int, int> id(
160 info->render_process_id(), info->render_view_id());
161 if (visible_renderer_ids->find(id) != visible_renderer_ids->end()) {
162 throttle = false;
163 break;
164 }
165 }
166
167 if (!throttle ) {
168 break;
169 }
170 }
171
172 iter->SetBackgrounded(throttle);
173 }
174 }
175
176 void WorkerPrioritySetter::OnRenderWidgetVisibilityChanged(
177 std::pair<int, int> id) {
178 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
179 std::set<std::pair<int, int> > visible_renderer_ids;
180
181 visible_renderer_ids.insert(id);
182
183 UpdateWorkerPrioritiesFromVisibleSet(&visible_renderer_ids);
184 }
185
186 void WorkerPrioritySetter::RegisterObserver() {
187 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
188 registrar_.Add(this, NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED,
189 NotificationService::AllBrowserContextsAndSources());
190 registrar_.Add(this, NOTIFICATION_RENDERER_PROCESS_CREATED,
191 NotificationService::AllBrowserContextsAndSources());
192 }
193
194 void WorkerPrioritySetter::Observe(int type,
195 const NotificationSource& source, const NotificationDetails& details) {
196 if (type == NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED) {
197 bool visible = *Details<bool>(details).ptr();
198
199 if (visible) {
200 int render_widget_id =
201 Source<RenderWidgetHost>(source).ptr()->GetRoutingID();
202 int render_process_pid =
203 Source<RenderWidgetHost>(source).ptr()->GetProcess()->GetID();
204
205 BrowserThread::PostTask(
206 BrowserThread::IO, FROM_HERE,
207 base::Bind(&WorkerPrioritySetter::OnRenderWidgetVisibilityChanged,
208 this, std::pair<int, int>(render_process_pid, render_widget_id)));
209 }
210 }
211 else if (type == NOTIFICATION_RENDERER_PROCESS_CREATED) {
212 PostTaskToGatherAndUpdateWorkerPriorities();
213 }
214 }
215
216 WorkerService* WorkerService::GetInstance() { 28 WorkerService* WorkerService::GetInstance() {
217 return WorkerServiceImpl::GetInstance(); 29 return WorkerServiceImpl::GetInstance();
218 } 30 }
219 31
220 WorkerServiceImpl* WorkerServiceImpl::GetInstance() { 32 WorkerServiceImpl* WorkerServiceImpl::GetInstance() {
221 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 33 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
222 return Singleton<WorkerServiceImpl>::get(); 34 return Singleton<WorkerServiceImpl>::get();
223 } 35 }
224 36
225 WorkerServiceImpl::WorkerServiceImpl() 37 WorkerServiceImpl::WorkerServiceImpl() : next_worker_route_id_(0) {
226 : priority_setter_(new WorkerPrioritySetter()),
227 next_worker_route_id_(0) {
228 } 38 }
229 39
230 WorkerServiceImpl::~WorkerServiceImpl() { 40 WorkerServiceImpl::~WorkerServiceImpl() {
231 // The observers in observers_ can't be used here because they might be 41 // The observers in observers_ can't be used here because they might be
232 // gone already. 42 // gone already.
233 } 43 }
234 44
235 void WorkerServiceImpl::OnWorkerMessageFilterClosing( 45 void WorkerServiceImpl::OnWorkerMessageFilterClosing(
236 WorkerMessageFilter* filter) { 46 WorkerMessageFilter* filter) {
237 for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) { 47 for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) {
(...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after
640 450
641 void WorkerServiceImpl::NotifyWorkerDestroyed( 451 void WorkerServiceImpl::NotifyWorkerDestroyed(
642 WorkerProcessHost* process, 452 WorkerProcessHost* process,
643 int worker_route_id) { 453 int worker_route_id) {
644 WorkerDevToolsManager::GetInstance()->WorkerDestroyed( 454 WorkerDevToolsManager::GetInstance()->WorkerDestroyed(
645 process, worker_route_id); 455 process, worker_route_id);
646 FOR_EACH_OBSERVER(WorkerServiceObserver, observers_, 456 FOR_EACH_OBSERVER(WorkerServiceObserver, observers_,
647 WorkerDestroyed(process->GetData().id, worker_route_id)); 457 WorkerDestroyed(process->GetData().id, worker_route_id));
648 } 458 }
649 459
650 void WorkerServiceImpl::NotifyWorkerProcessCreated() {
651 priority_setter_->NotifyWorkerProcessCreated();
652 }
653
654 WorkerProcessHost::WorkerInstance* WorkerServiceImpl::FindSharedWorkerInstance( 460 WorkerProcessHost::WorkerInstance* WorkerServiceImpl::FindSharedWorkerInstance(
655 const GURL& url, 461 const GURL& url,
656 const string16& name, 462 const string16& name,
657 const WorkerStoragePartition& partition, 463 const WorkerStoragePartition& partition,
658 ResourceContext* resource_context) { 464 ResourceContext* resource_context) {
659 for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) { 465 for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) {
660 for (WorkerProcessHost::Instances::iterator instance_iter = 466 for (WorkerProcessHost::Instances::iterator instance_iter =
661 iter->mutable_instances().begin(); 467 iter->mutable_instances().begin();
662 instance_iter != iter->mutable_instances().end(); 468 instance_iter != iter->mutable_instances().end();
663 ++instance_iter) { 469 ++instance_iter) {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
714 return instance; 520 return instance;
715 521
716 // No existing pending worker - create a new one. 522 // No existing pending worker - create a new one.
717 WorkerProcessHost::WorkerInstance pending( 523 WorkerProcessHost::WorkerInstance pending(
718 url, true, name, resource_context, partition); 524 url, true, name, resource_context, partition);
719 pending_shared_workers_.push_back(pending); 525 pending_shared_workers_.push_back(pending);
720 return &pending_shared_workers_.back(); 526 return &pending_shared_workers_.back();
721 } 527 }
722 528
723 } // namespace content 529 } // namespace content
OLDNEW
« no previous file with comments | « trunk/src/content/browser/worker_host/worker_service_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698