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

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

Issue 15465006: Revert 200932 "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 // Posts a task to the UI thread to register to receive notifications.
44 void Initialize();
45
46 // Invoked by WorkerServiceImpl when a worker process is created.
47 void NotifyWorkerProcessCreated();
48
49 private:
50 friend class base::RefCountedThreadSafe<WorkerPrioritySetter>;
51 friend struct BrowserThread::DeleteOnThread<BrowserThread::UI>;
52 friend class base::DeleteHelper<WorkerPrioritySetter>;
53 virtual ~WorkerPrioritySetter();
54
55 // Posts a task to perform a worker priority update.
56 void PostTaskToGatherAndUpdateWorkerPriorities();
57
58 // Gathers up a list of the visible tabs and then updates priorities for
59 // all the shared workers.
60 void GatherVisibleIDsAndUpdateWorkerPriorities();
61
62 // Registers as an observer to receive notifications about
63 // widgets being shown.
64 void RegisterObserver();
65
66 // Sets priorities for shared workers given a set of visible tabs (as a
67 // std::set of std::pair<render_process, render_view> ids.
68 void UpdateWorkerPrioritiesFromVisibleSet(
69 const std::set<std::pair<int, int> >* visible);
70
71 // Called to refresh worker priorities when focus changes between tabs.
72 void OnRenderWidgetVisibilityChanged(std::pair<int, int>);
73
74 // NotificationObserver implementation.
75 virtual void Observe(int type,
76 const NotificationSource& source,
77 const NotificationDetails& details) OVERRIDE;
78
79 NotificationRegistrar registrar_;
80 };
81
82 WorkerPrioritySetter::WorkerPrioritySetter() {
83 }
84
85 WorkerPrioritySetter::~WorkerPrioritySetter() {
86 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
87 }
88
89 void WorkerPrioritySetter::Initialize() {
90 BrowserThread::PostTask(
91 BrowserThread::UI, FROM_HERE,
92 base::Bind(&WorkerPrioritySetter::RegisterObserver, this));
93 }
94
95 void WorkerPrioritySetter::NotifyWorkerProcessCreated() {
96 PostTaskToGatherAndUpdateWorkerPriorities();
97 }
98
99 void WorkerPrioritySetter::PostTaskToGatherAndUpdateWorkerPriorities() {
100 BrowserThread::PostTask(
101 BrowserThread::UI, FROM_HERE,
102 base::Bind(
103 &WorkerPrioritySetter::GatherVisibleIDsAndUpdateWorkerPriorities,
104 this));
105 }
106
107 void WorkerPrioritySetter::GatherVisibleIDsAndUpdateWorkerPriorities() {
108 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
109 std::set<std::pair<int, int> >* visible_renderer_ids =
110 new std::set<std::pair<int, int> >();
111
112 // Gather up all the visible renderer process/view pairs
113 for (RenderProcessHost::iterator it =
114 RenderProcessHost::AllHostsIterator();
115 !it.IsAtEnd(); it.Advance()) {
116 RenderProcessHost* render_process_host = it.GetCurrentValue();
117 if (render_process_host->VisibleWidgetCount()) {
118 for (RenderProcessHost::RenderWidgetHostsIterator rit =
119 render_process_host->GetRenderWidgetHostsIterator(); !rit.IsAtEnd();
120 rit.Advance()) {
121 RenderWidgetHost* render_widget =
122 render_process_host->GetRenderWidgetHostByID(rit.GetCurrentKey());
123 if (render_widget) {
124 RenderWidgetHostView* render_view = render_widget->GetView();
125 if (render_view && render_view->IsShowing()) {
126 visible_renderer_ids->insert(
127 std::pair<int, int>(render_process_host->GetID(),
128 render_widget->GetRoutingID()));
129 }
130 }
131 }
132 }
133 }
134
135 BrowserThread::PostTask(
136 BrowserThread::IO, FROM_HERE,
137 base::Bind(&WorkerPrioritySetter::UpdateWorkerPrioritiesFromVisibleSet,
138 this, base::Owned(visible_renderer_ids)));
139 }
140
141 void WorkerPrioritySetter::UpdateWorkerPrioritiesFromVisibleSet(
142 const std::set<std::pair<int, int> >* visible_renderer_ids) {
143 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
144
145 for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) {
146 if (!iter->process_launched())
147 continue;
148 bool throttle = true;
149
150 for (WorkerProcessHost::Instances::const_iterator instance =
151 iter->instances().begin(); instance != iter->instances().end();
152 ++instance) {
153
154 // This code assumes one worker per process
155 WorkerProcessHost::Instances::const_iterator first_instance =
156 iter->instances().begin();
157 if (first_instance == iter->instances().end())
158 continue;
159
160 WorkerDocumentSet::DocumentInfoSet::const_iterator info =
161 first_instance->worker_document_set()->documents().begin();
162
163 for (; info != first_instance->worker_document_set()->documents().end();
164 ++info) {
165 std::pair<int, int> id(
166 info->render_process_id(), info->render_view_id());
167 if (visible_renderer_ids->find(id) != visible_renderer_ids->end()) {
168 throttle = false;
169 break;
170 }
171 }
172
173 if (!throttle ) {
174 break;
175 }
176 }
177
178 iter->SetBackgrounded(throttle);
179 }
180 }
181
182 void WorkerPrioritySetter::OnRenderWidgetVisibilityChanged(
183 std::pair<int, int> id) {
184 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
185 std::set<std::pair<int, int> > visible_renderer_ids;
186
187 visible_renderer_ids.insert(id);
188
189 UpdateWorkerPrioritiesFromVisibleSet(&visible_renderer_ids);
190 }
191
192 void WorkerPrioritySetter::RegisterObserver() {
193 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
194 registrar_.Add(this, NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED,
195 NotificationService::AllBrowserContextsAndSources());
196 registrar_.Add(this, NOTIFICATION_RENDERER_PROCESS_CREATED,
197 NotificationService::AllBrowserContextsAndSources());
198 }
199
200 void WorkerPrioritySetter::Observe(int type,
201 const NotificationSource& source, const NotificationDetails& details) {
202 if (type == NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED) {
203 bool visible = *Details<bool>(details).ptr();
204
205 if (visible) {
206 int render_widget_id =
207 Source<RenderWidgetHost>(source).ptr()->GetRoutingID();
208 int render_process_pid =
209 Source<RenderWidgetHost>(source).ptr()->GetProcess()->GetID();
210
211 BrowserThread::PostTask(
212 BrowserThread::IO, FROM_HERE,
213 base::Bind(&WorkerPrioritySetter::OnRenderWidgetVisibilityChanged,
214 this, std::pair<int, int>(render_process_pid, render_widget_id)));
215 }
216 }
217 else if (type == NOTIFICATION_RENDERER_PROCESS_CREATED) {
218 PostTaskToGatherAndUpdateWorkerPriorities();
219 }
220 }
221
222 WorkerService* WorkerService::GetInstance() { 28 WorkerService* WorkerService::GetInstance() {
223 return WorkerServiceImpl::GetInstance(); 29 return WorkerServiceImpl::GetInstance();
224 } 30 }
225 31
226 WorkerServiceImpl* WorkerServiceImpl::GetInstance() { 32 WorkerServiceImpl* WorkerServiceImpl::GetInstance() {
227 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 33 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
228 return Singleton<WorkerServiceImpl>::get(); 34 return Singleton<WorkerServiceImpl>::get();
229 } 35 }
230 36
231 WorkerServiceImpl::WorkerServiceImpl() 37 WorkerServiceImpl::WorkerServiceImpl() : next_worker_route_id_(0) {
232 : priority_setter_(new WorkerPrioritySetter()),
233 next_worker_route_id_(0) {
234 priority_setter_->Initialize();
235 } 38 }
236 39
237 WorkerServiceImpl::~WorkerServiceImpl() { 40 WorkerServiceImpl::~WorkerServiceImpl() {
238 // 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
239 // gone already. 42 // gone already.
240 } 43 }
241 44
242 void WorkerServiceImpl::OnWorkerMessageFilterClosing( 45 void WorkerServiceImpl::OnWorkerMessageFilterClosing(
243 WorkerMessageFilter* filter) { 46 WorkerMessageFilter* filter) {
244 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
647 450
648 void WorkerServiceImpl::NotifyWorkerDestroyed( 451 void WorkerServiceImpl::NotifyWorkerDestroyed(
649 WorkerProcessHost* process, 452 WorkerProcessHost* process,
650 int worker_route_id) { 453 int worker_route_id) {
651 WorkerDevToolsManager::GetInstance()->WorkerDestroyed( 454 WorkerDevToolsManager::GetInstance()->WorkerDestroyed(
652 process, worker_route_id); 455 process, worker_route_id);
653 FOR_EACH_OBSERVER(WorkerServiceObserver, observers_, 456 FOR_EACH_OBSERVER(WorkerServiceObserver, observers_,
654 WorkerDestroyed(process->GetData().id, worker_route_id)); 457 WorkerDestroyed(process->GetData().id, worker_route_id));
655 } 458 }
656 459
657 void WorkerServiceImpl::NotifyWorkerProcessCreated() {
658 priority_setter_->NotifyWorkerProcessCreated();
659 }
660
661 WorkerProcessHost::WorkerInstance* WorkerServiceImpl::FindSharedWorkerInstance( 460 WorkerProcessHost::WorkerInstance* WorkerServiceImpl::FindSharedWorkerInstance(
662 const GURL& url, 461 const GURL& url,
663 const string16& name, 462 const string16& name,
664 const WorkerStoragePartition& partition, 463 const WorkerStoragePartition& partition,
665 ResourceContext* resource_context) { 464 ResourceContext* resource_context) {
666 for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) { 465 for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) {
667 for (WorkerProcessHost::Instances::iterator instance_iter = 466 for (WorkerProcessHost::Instances::iterator instance_iter =
668 iter->mutable_instances().begin(); 467 iter->mutable_instances().begin();
669 instance_iter != iter->mutable_instances().end(); 468 instance_iter != iter->mutable_instances().end();
670 ++instance_iter) { 469 ++instance_iter) {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
721 return instance; 520 return instance;
722 521
723 // No existing pending worker - create a new one. 522 // No existing pending worker - create a new one.
724 WorkerProcessHost::WorkerInstance pending( 523 WorkerProcessHost::WorkerInstance pending(
725 url, true, name, resource_context, partition); 524 url, true, name, resource_context, partition);
726 pending_shared_workers_.push_back(pending); 525 pending_shared_workers_.push_back(pending);
727 return &pending_shared_workers_.back(); 526 return &pending_shared_workers_.back();
728 } 527 }
729 528
730 } // 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