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

Side by Side Diff: content/browser/shared_worker/shared_worker_service_impl.cc

Issue 187533002: Add SharedWorkerServiceImpl::CheckWorkerDependency(). (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@ExternalClient
Patch Set: Incorporated jochen's comments. Created 6 years, 9 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/shared_worker/shared_worker_service_impl.h" 5 #include "content/browser/shared_worker/shared_worker_service_impl.h"
6 6
7 #include <algorithm>
8 #include <iterator>
9 #include <set>
10 #include <vector>
11
12 #include "content/browser/renderer_host/render_process_host_impl.h"
7 #include "content/browser/shared_worker/shared_worker_host.h" 13 #include "content/browser/shared_worker/shared_worker_host.h"
8 #include "content/browser/shared_worker/shared_worker_instance.h" 14 #include "content/browser/shared_worker/shared_worker_instance.h"
9 #include "content/browser/shared_worker/shared_worker_message_filter.h" 15 #include "content/browser/shared_worker/shared_worker_message_filter.h"
10 #include "content/browser/worker_host/worker_document_set.h" 16 #include "content/browser/worker_host/worker_document_set.h"
11 #include "content/common/view_messages.h" 17 #include "content/common/view_messages.h"
12 #include "content/common/worker_messages.h" 18 #include "content/common/worker_messages.h"
13 #include "content/public/browser/browser_thread.h" 19 #include "content/public/browser/browser_thread.h"
14 #include "content/public/browser/worker_service_observer.h" 20 #include "content/public/browser/worker_service_observer.h"
15 21
16 namespace content { 22 namespace content {
23 namespace {
24
25 class ScopedWorkerDependencyChecker {
26 public:
27 explicit ScopedWorkerDependencyChecker(SharedWorkerServiceImpl* service)
28 : service_(service) {}
29 ~ScopedWorkerDependencyChecker() { service_->CheckWorkerDependency(); }
30
31 private:
32 SharedWorkerServiceImpl* service_;
33 DISALLOW_COPY_AND_ASSIGN(ScopedWorkerDependencyChecker);
34 };
35
36 void UpdateWorkerDependencyOnUI(const std::vector<int>& added_ids,
37 const std::vector<int>& removed_ids) {
38 for (size_t i = 0; i < added_ids.size(); ++i) {
39 RenderProcessHostImpl* render_process_host_impl =
40 static_cast<RenderProcessHostImpl*>(
41 RenderProcessHost::FromID(added_ids[i]));
42 if (!render_process_host_impl)
43 continue;
44 render_process_host_impl->IncrementWorkerRefCount();
45 }
46 for (size_t i = 0; i < removed_ids.size(); ++i) {
47 RenderProcessHostImpl* render_process_host_impl =
48 static_cast<RenderProcessHostImpl*>(
49 RenderProcessHost::FromID(removed_ids[i]));
50 if (!render_process_host_impl)
51 continue;
52 render_process_host_impl->DecrementWorkerRefCount();
53 }
54 }
55
56 void UpdateWorkerDependency(const std::vector<int>& added_ids,
57 const std::vector<int>& removed_ids) {
58 BrowserThread::PostTask(
59 BrowserThread::UI,
60 FROM_HERE,
61 base::Bind(&UpdateWorkerDependencyOnUI, added_ids, removed_ids));
62 }
63
64 } // namespace
17 65
18 SharedWorkerServiceImpl* SharedWorkerServiceImpl::GetInstance() { 66 SharedWorkerServiceImpl* SharedWorkerServiceImpl::GetInstance() {
19 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 67 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
20 return Singleton<SharedWorkerServiceImpl>::get(); 68 return Singleton<SharedWorkerServiceImpl>::get();
21 } 69 }
22 70
23 SharedWorkerServiceImpl::SharedWorkerServiceImpl() { 71 SharedWorkerServiceImpl::SharedWorkerServiceImpl()
24 } 72 : update_worker_dependency_(UpdateWorkerDependency) {}
25 73
26 SharedWorkerServiceImpl::~SharedWorkerServiceImpl() { 74 SharedWorkerServiceImpl::~SharedWorkerServiceImpl() {}
75
76 void SharedWorkerServiceImpl::ResetForTesting() {
77 last_worker_depended_renderers_.clear();
78 worker_hosts_.clear();
79 observers_.Clear();
80 update_worker_dependency_ = UpdateWorkerDependency;
27 } 81 }
28 82
29 bool SharedWorkerServiceImpl::TerminateWorker(int process_id, int route_id) { 83 bool SharedWorkerServiceImpl::TerminateWorker(int process_id, int route_id) {
30 SharedWorkerHost* host = 84 SharedWorkerHost* host =
31 worker_hosts_.get(std::make_pair(process_id, route_id)); 85 worker_hosts_.get(std::make_pair(process_id, route_id));
32 if (!host || !host->instance()) 86 if (!host || !host->instance())
33 return false; 87 return false;
34 host->TerminateWorker(); 88 host->TerminateWorker();
35 return true; 89 return true;
36 } 90 }
(...skipping 29 matching lines...) Expand all
66 } 120 }
67 121
68 void SharedWorkerServiceImpl::CreateWorker( 122 void SharedWorkerServiceImpl::CreateWorker(
69 const ViewHostMsg_CreateWorker_Params& params, 123 const ViewHostMsg_CreateWorker_Params& params,
70 int route_id, 124 int route_id,
71 SharedWorkerMessageFilter* filter, 125 SharedWorkerMessageFilter* filter,
72 ResourceContext* resource_context, 126 ResourceContext* resource_context,
73 const WorkerStoragePartition& partition, 127 const WorkerStoragePartition& partition,
74 bool* url_mismatch) { 128 bool* url_mismatch) {
75 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 129 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
130 ScopedWorkerDependencyChecker checker(this);
76 *url_mismatch = false; 131 *url_mismatch = false;
77 SharedWorkerInstance* existing_instance = 132 SharedWorkerInstance* existing_instance =
78 FindSharedWorkerInstance( 133 FindSharedWorkerInstance(
79 params.url, params.name, partition, resource_context); 134 params.url, params.name, partition, resource_context);
80 if (existing_instance) { 135 if (existing_instance) {
81 if (params.url != existing_instance->url()) { 136 if (params.url != existing_instance->url()) {
82 *url_mismatch = true; 137 *url_mismatch = true;
83 return; 138 return;
84 } 139 }
85 if (existing_instance->load_failed()) { 140 if (existing_instance->load_failed()) {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 iter != worker_hosts_.end(); 183 iter != worker_hosts_.end();
129 ++iter) { 184 ++iter) {
130 if (iter->second->FilterMessage(message, filter)) 185 if (iter->second->FilterMessage(message, filter))
131 return; 186 return;
132 } 187 }
133 } 188 }
134 189
135 void SharedWorkerServiceImpl::DocumentDetached( 190 void SharedWorkerServiceImpl::DocumentDetached(
136 unsigned long long document_id, 191 unsigned long long document_id,
137 SharedWorkerMessageFilter* filter) { 192 SharedWorkerMessageFilter* filter) {
193 ScopedWorkerDependencyChecker checker(this);
138 for (WorkerHostMap::const_iterator iter = worker_hosts_.begin(); 194 for (WorkerHostMap::const_iterator iter = worker_hosts_.begin();
139 iter != worker_hosts_.end(); 195 iter != worker_hosts_.end();
140 ++iter) { 196 ++iter) {
141 iter->second->DocumentDetached(filter, document_id); 197 iter->second->DocumentDetached(filter, document_id);
142 } 198 }
143 } 199 }
144 200
145 void SharedWorkerServiceImpl::WorkerContextClosed( 201 void SharedWorkerServiceImpl::WorkerContextClosed(
146 int worker_route_id, 202 int worker_route_id,
147 SharedWorkerMessageFilter* filter) { 203 SharedWorkerMessageFilter* filter) {
204 ScopedWorkerDependencyChecker checker(this);
148 if (SharedWorkerHost* host = FindSharedWorkerHost(filter, worker_route_id)) 205 if (SharedWorkerHost* host = FindSharedWorkerHost(filter, worker_route_id))
149 host->WorkerContextClosed(); 206 host->WorkerContextClosed();
150 } 207 }
151 208
152 void SharedWorkerServiceImpl::WorkerContextDestroyed( 209 void SharedWorkerServiceImpl::WorkerContextDestroyed(
153 int worker_route_id, 210 int worker_route_id,
154 SharedWorkerMessageFilter* filter) { 211 SharedWorkerMessageFilter* filter) {
212 ScopedWorkerDependencyChecker checker(this);
155 scoped_ptr<SharedWorkerHost> host = 213 scoped_ptr<SharedWorkerHost> host =
156 worker_hosts_.take_and_erase(std::make_pair(filter->render_process_id(), 214 worker_hosts_.take_and_erase(std::make_pair(filter->render_process_id(),
157 worker_route_id)); 215 worker_route_id));
158 if (!host) 216 if (!host)
159 return; 217 return;
160 host->WorkerContextDestroyed(); 218 host->WorkerContextDestroyed();
161 } 219 }
162 220
163 void SharedWorkerServiceImpl::WorkerScriptLoaded( 221 void SharedWorkerServiceImpl::WorkerScriptLoaded(
164 int worker_route_id, 222 int worker_route_id,
165 SharedWorkerMessageFilter* filter) { 223 SharedWorkerMessageFilter* filter) {
166 if (SharedWorkerHost* host = FindSharedWorkerHost(filter, worker_route_id)) 224 if (SharedWorkerHost* host = FindSharedWorkerHost(filter, worker_route_id))
167 host->WorkerScriptLoaded(); 225 host->WorkerScriptLoaded();
168 } 226 }
169 227
170 void SharedWorkerServiceImpl::WorkerScriptLoadFailed( 228 void SharedWorkerServiceImpl::WorkerScriptLoadFailed(
171 int worker_route_id, 229 int worker_route_id,
172 SharedWorkerMessageFilter* filter) { 230 SharedWorkerMessageFilter* filter) {
231 ScopedWorkerDependencyChecker checker(this);
173 scoped_ptr<SharedWorkerHost> host = 232 scoped_ptr<SharedWorkerHost> host =
174 worker_hosts_.take_and_erase(std::make_pair(filter->render_process_id(), 233 worker_hosts_.take_and_erase(std::make_pair(filter->render_process_id(),
175 worker_route_id)); 234 worker_route_id));
176 if (!host) 235 if (!host)
177 return; 236 return;
178 host->WorkerScriptLoadFailed(); 237 host->WorkerScriptLoadFailed();
179 } 238 }
180 239
181 void SharedWorkerServiceImpl::WorkerConnected( 240 void SharedWorkerServiceImpl::WorkerConnected(
182 int message_port_id, 241 int message_port_id,
(...skipping 29 matching lines...) Expand all
212 const GURL& url, 271 const GURL& url,
213 const base::string16& name, 272 const base::string16& name,
214 bool* result, 273 bool* result,
215 SharedWorkerMessageFilter* filter) { 274 SharedWorkerMessageFilter* filter) {
216 if (SharedWorkerHost* host = FindSharedWorkerHost(filter, worker_route_id)) 275 if (SharedWorkerHost* host = FindSharedWorkerHost(filter, worker_route_id))
217 host->AllowIndexedDB(url, name, result); 276 host->AllowIndexedDB(url, name, result);
218 } 277 }
219 278
220 void SharedWorkerServiceImpl::OnSharedWorkerMessageFilterClosing( 279 void SharedWorkerServiceImpl::OnSharedWorkerMessageFilterClosing(
221 SharedWorkerMessageFilter* filter) { 280 SharedWorkerMessageFilter* filter) {
281 ScopedWorkerDependencyChecker checker(this);
222 std::vector<ProcessRouteIdPair> remove_list; 282 std::vector<ProcessRouteIdPair> remove_list;
223 for (WorkerHostMap::iterator iter = worker_hosts_.begin(); 283 for (WorkerHostMap::iterator iter = worker_hosts_.begin();
224 iter != worker_hosts_.end(); 284 iter != worker_hosts_.end();
225 ++iter) { 285 ++iter) {
226 iter->second->FilterShutdown(filter); 286 iter->second->FilterShutdown(filter);
227 if (iter->first.first == filter->render_process_id()) 287 if (iter->first.first == filter->render_process_id())
228 remove_list.push_back(iter->first); 288 remove_list.push_back(iter->first);
229 } 289 }
230 for (size_t i = 0; i < remove_list.size(); ++i) 290 for (size_t i = 0; i < remove_list.size(); ++i)
231 worker_hosts_.erase(remove_list[i]); 291 worker_hosts_.erase(remove_list[i]);
(...skipping 14 matching lines...) Expand all
246 for (WorkerHostMap::const_iterator iter = worker_hosts_.begin(); 306 for (WorkerHostMap::const_iterator iter = worker_hosts_.begin();
247 iter != worker_hosts_.end(); 307 iter != worker_hosts_.end();
248 ++iter) { 308 ++iter) {
249 SharedWorkerInstance* instance = iter->second->instance(); 309 SharedWorkerInstance* instance = iter->second->instance();
250 if (instance && instance->Matches(url, name, partition, resource_context)) 310 if (instance && instance->Matches(url, name, partition, resource_context))
251 return instance; 311 return instance;
252 } 312 }
253 return NULL; 313 return NULL;
254 } 314 }
255 315
316 const std::set<int>
317 SharedWorkerServiceImpl::GetRenderersWithWorkerDependency() {
318 std::set<int> dependent_renderers;
319 for (WorkerHostMap::iterator host_iter = worker_hosts_.begin();
320 host_iter != worker_hosts_.end();
321 ++host_iter) {
322 const int process_id = host_iter->first.first;
323 if (dependent_renderers.count(process_id))
324 continue;
325 SharedWorkerInstance* instance = host_iter->second->instance();
326 if (instance &&
327 instance->worker_document_set()->ContainsExternalRenderer(process_id)) {
328 dependent_renderers.insert(process_id);
329 }
330 }
331 return dependent_renderers;
332 }
333
334 void SharedWorkerServiceImpl::CheckWorkerDependency() {
335 const std::set<int> current_worker_depended_renderers =
336 GetRenderersWithWorkerDependency();
337 std::vector<int> added_items;
338 std::vector<int> removed_items;
339 std::set_difference(current_worker_depended_renderers.begin(),
340 current_worker_depended_renderers.end(),
341 last_worker_depended_renderers_.begin(),
342 last_worker_depended_renderers_.end(),
343 std::back_inserter(added_items));
344 std::set_difference(last_worker_depended_renderers_.begin(),
345 last_worker_depended_renderers_.end(),
346 current_worker_depended_renderers.begin(),
347 current_worker_depended_renderers.end(),
348 std::back_inserter(removed_items));
349 if (!added_items.empty() || !removed_items.empty()) {
350 last_worker_depended_renderers_ = current_worker_depended_renderers;
351 update_worker_dependency_(added_items, removed_items);
352 }
353 }
354
355 void SharedWorkerServiceImpl::ChangeUpdateWorkerDependencyFuncForTesting(
356 UpdateWorkerDependencyFunc new_func) {
357 update_worker_dependency_ = new_func;
358 }
359
256 } // namespace content 360 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698