[refactor] More post-NSS WebCrypto cleanups (utility functions).
[chromium-blink-merge.git] / content / browser / shared_worker / shared_worker_service_impl.cc
blob221c1ddf6a865aee0ebb6ac01d063d9fbb6a51b5
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
3 // found in the LICENSE file.
5 #include "content/browser/shared_worker/shared_worker_service_impl.h"
7 #include <algorithm>
8 #include <iterator>
9 #include <set>
10 #include <vector>
12 #include "base/callback.h"
13 #include "base/memory/ref_counted.h"
14 #include "content/browser/devtools/shared_worker_devtools_manager.h"
15 #include "content/browser/renderer_host/render_process_host_impl.h"
16 #include "content/browser/shared_worker/shared_worker_host.h"
17 #include "content/browser/shared_worker/shared_worker_instance.h"
18 #include "content/browser/shared_worker/shared_worker_message_filter.h"
19 #include "content/browser/shared_worker/worker_document_set.h"
20 #include "content/common/view_messages.h"
21 #include "content/common/worker_messages.h"
22 #include "content/public/browser/browser_thread.h"
23 #include "content/public/browser/worker_service_observer.h"
25 namespace content {
27 WorkerService* WorkerService::GetInstance() {
28 return SharedWorkerServiceImpl::GetInstance();
31 namespace {
33 class ScopedWorkerDependencyChecker {
34 public:
35 explicit ScopedWorkerDependencyChecker(SharedWorkerServiceImpl* service)
36 : service_(service) {}
37 ScopedWorkerDependencyChecker(SharedWorkerServiceImpl* service,
38 base::Closure done_closure)
39 : service_(service), done_closure_(done_closure) {}
40 ~ScopedWorkerDependencyChecker() {
41 service_->CheckWorkerDependency();
42 if (!done_closure_.is_null())
43 done_closure_.Run();
46 private:
47 SharedWorkerServiceImpl* service_;
48 base::Closure done_closure_;
49 DISALLOW_COPY_AND_ASSIGN(ScopedWorkerDependencyChecker);
52 void UpdateWorkerDependencyOnUI(const std::vector<int>& added_ids,
53 const std::vector<int>& removed_ids) {
54 for (size_t i = 0; i < added_ids.size(); ++i) {
55 RenderProcessHostImpl* render_process_host_impl =
56 static_cast<RenderProcessHostImpl*>(
57 RenderProcessHost::FromID(added_ids[i]));
58 if (!render_process_host_impl)
59 continue;
60 render_process_host_impl->IncrementWorkerRefCount();
62 for (size_t i = 0; i < removed_ids.size(); ++i) {
63 RenderProcessHostImpl* render_process_host_impl =
64 static_cast<RenderProcessHostImpl*>(
65 RenderProcessHost::FromID(removed_ids[i]));
66 if (!render_process_host_impl)
67 continue;
68 render_process_host_impl->DecrementWorkerRefCount();
72 void UpdateWorkerDependency(const std::vector<int>& added_ids,
73 const std::vector<int>& removed_ids) {
74 BrowserThread::PostTask(
75 BrowserThread::UI,
76 FROM_HERE,
77 base::Bind(&UpdateWorkerDependencyOnUI, added_ids, removed_ids));
80 void DecrementWorkerRefCount(int process_id) {
81 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
82 BrowserThread::PostTask(BrowserThread::UI,
83 FROM_HERE,
84 base::Bind(&DecrementWorkerRefCount, process_id));
85 return;
87 RenderProcessHostImpl* render_process_host_impl =
88 static_cast<RenderProcessHostImpl*>(
89 RenderProcessHost::FromID(process_id));
90 if (render_process_host_impl)
91 render_process_host_impl->DecrementWorkerRefCount();
94 bool TryIncrementWorkerRefCount(int worker_process_id) {
95 RenderProcessHostImpl* render_process = static_cast<RenderProcessHostImpl*>(
96 RenderProcessHost::FromID(worker_process_id));
97 if (!render_process || render_process->FastShutdownStarted()) {
98 return false;
100 render_process->IncrementWorkerRefCount();
101 return true;
104 } // namespace
106 class SharedWorkerServiceImpl::SharedWorkerPendingInstance {
107 public:
108 struct SharedWorkerPendingRequest {
109 SharedWorkerPendingRequest(SharedWorkerMessageFilter* filter,
110 int route_id,
111 unsigned long long document_id,
112 int render_process_id,
113 int render_frame_route_id)
114 : filter(filter),
115 route_id(route_id),
116 document_id(document_id),
117 render_process_id(render_process_id),
118 render_frame_route_id(render_frame_route_id) {}
119 SharedWorkerMessageFilter* const filter;
120 const int route_id;
121 const unsigned long long document_id;
122 const int render_process_id;
123 const int render_frame_route_id;
126 typedef ScopedVector<SharedWorkerPendingRequest> SharedWorkerPendingRequests;
128 explicit SharedWorkerPendingInstance(
129 scoped_ptr<SharedWorkerInstance> instance)
130 : instance_(instance.Pass()) {}
131 ~SharedWorkerPendingInstance() {}
132 SharedWorkerInstance* instance() { return instance_.get(); }
133 SharedWorkerInstance* release_instance() { return instance_.release(); }
134 SharedWorkerPendingRequests* requests() { return &requests_; }
135 SharedWorkerMessageFilter* FindFilter(int process_id) {
136 for (size_t i = 0; i < requests_.size(); ++i) {
137 if (requests_[i]->render_process_id == process_id)
138 return requests_[i]->filter;
140 return NULL;
142 void AddRequest(scoped_ptr<SharedWorkerPendingRequest> request_info) {
143 requests_.push_back(request_info.release());
145 void RemoveRequest(int process_id) {
146 for (SharedWorkerPendingRequests::iterator request_itr = requests_.begin();
147 request_itr != requests_.end();) {
148 if ((*request_itr)->render_process_id == process_id)
149 request_itr = requests_.erase(request_itr);
150 else
151 ++request_itr;
154 void RegisterToSharedWorkerHost(SharedWorkerHost* host) {
155 for (size_t i = 0; i < requests_.size(); ++i) {
156 SharedWorkerPendingRequest* request = requests_[i];
157 host->AddFilter(request->filter, request->route_id);
158 host->worker_document_set()->Add(request->filter,
159 request->document_id,
160 request->render_process_id,
161 request->render_frame_route_id);
164 void SendWorkerCreatedMessages() {
165 for (size_t i = 0; i < requests_.size(); ++i) {
166 SharedWorkerPendingRequest* request = requests_[i];
167 request->filter->Send(new ViewMsg_WorkerCreated(request->route_id));
171 private:
172 scoped_ptr<SharedWorkerInstance> instance_;
173 SharedWorkerPendingRequests requests_;
174 DISALLOW_COPY_AND_ASSIGN(SharedWorkerPendingInstance);
177 class SharedWorkerServiceImpl::SharedWorkerReserver
178 : public base::RefCountedThreadSafe<SharedWorkerReserver> {
179 public:
180 SharedWorkerReserver(int pending_instance_id,
181 int worker_process_id,
182 int worker_route_id,
183 bool is_new_worker,
184 const SharedWorkerInstance& instance)
185 : worker_process_id_(worker_process_id),
186 worker_route_id_(worker_route_id),
187 is_new_worker_(is_new_worker),
188 instance_(instance) {}
190 void TryReserve(const base::Callback<void(bool)>& success_cb,
191 const base::Closure& failure_cb,
192 bool (*try_increment_worker_ref_count)(int)) {
193 DCHECK_CURRENTLY_ON(BrowserThread::UI);
194 if (!try_increment_worker_ref_count(worker_process_id_)) {
195 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, failure_cb);
196 return;
198 bool pause_on_start = false;
199 if (is_new_worker_) {
200 pause_on_start =
201 SharedWorkerDevToolsManager::GetInstance()->WorkerCreated(
202 worker_process_id_, worker_route_id_, instance_);
204 BrowserThread::PostTask(
205 BrowserThread::IO, FROM_HERE, base::Bind(success_cb, pause_on_start));
208 private:
209 friend class base::RefCountedThreadSafe<SharedWorkerReserver>;
210 ~SharedWorkerReserver() {}
212 const int worker_process_id_;
213 const int worker_route_id_;
214 const bool is_new_worker_;
215 const SharedWorkerInstance instance_;
218 // static
219 bool (*SharedWorkerServiceImpl::s_try_increment_worker_ref_count_)(int) =
220 TryIncrementWorkerRefCount;
222 SharedWorkerServiceImpl* SharedWorkerServiceImpl::GetInstance() {
223 DCHECK_CURRENTLY_ON(BrowserThread::IO);
224 return base::Singleton<SharedWorkerServiceImpl>::get();
227 SharedWorkerServiceImpl::SharedWorkerServiceImpl()
228 : update_worker_dependency_(UpdateWorkerDependency),
229 next_pending_instance_id_(0) {
232 SharedWorkerServiceImpl::~SharedWorkerServiceImpl() {}
234 void SharedWorkerServiceImpl::ResetForTesting() {
235 last_worker_depended_renderers_.clear();
236 worker_hosts_.clear();
237 observers_.Clear();
238 update_worker_dependency_ = UpdateWorkerDependency;
239 s_try_increment_worker_ref_count_ = TryIncrementWorkerRefCount;
242 bool SharedWorkerServiceImpl::TerminateWorker(int process_id, int route_id) {
243 SharedWorkerHost* host =
244 worker_hosts_.get(std::make_pair(process_id, route_id));
245 if (!host || !host->instance())
246 return false;
247 host->TerminateWorker();
248 return true;
251 std::vector<WorkerService::WorkerInfo> SharedWorkerServiceImpl::GetWorkers() {
252 std::vector<WorkerService::WorkerInfo> results;
253 for (WorkerHostMap::const_iterator iter = worker_hosts_.begin();
254 iter != worker_hosts_.end();
255 ++iter) {
256 SharedWorkerHost* host = iter->second;
257 const SharedWorkerInstance* instance = host->instance();
258 if (instance) {
259 WorkerService::WorkerInfo info;
260 info.url = instance->url();
261 info.name = instance->name();
262 info.route_id = host->worker_route_id();
263 info.process_id = host->process_id();
264 info.handle = host->container_render_filter()->PeerHandle();
265 results.push_back(info);
268 return results;
271 void SharedWorkerServiceImpl::AddObserver(WorkerServiceObserver* observer) {
272 DCHECK_CURRENTLY_ON(BrowserThread::IO);
273 observers_.AddObserver(observer);
276 void SharedWorkerServiceImpl::RemoveObserver(WorkerServiceObserver* observer) {
277 DCHECK_CURRENTLY_ON(BrowserThread::IO);
278 observers_.RemoveObserver(observer);
281 void SharedWorkerServiceImpl::CreateWorker(
282 const ViewHostMsg_CreateWorker_Params& params,
283 int route_id,
284 SharedWorkerMessageFilter* filter,
285 ResourceContext* resource_context,
286 const WorkerStoragePartitionId& partition_id,
287 bool* url_mismatch) {
288 DCHECK_CURRENTLY_ON(BrowserThread::IO);
289 *url_mismatch = false;
290 scoped_ptr<SharedWorkerInstance> instance(
291 new SharedWorkerInstance(params.url,
292 params.name,
293 params.content_security_policy,
294 params.security_policy_type,
295 resource_context,
296 partition_id));
297 scoped_ptr<SharedWorkerPendingInstance::SharedWorkerPendingRequest> request(
298 new SharedWorkerPendingInstance::SharedWorkerPendingRequest(
299 filter,
300 route_id,
301 params.document_id,
302 filter->render_process_id(),
303 params.render_frame_route_id));
304 if (SharedWorkerPendingInstance* pending = FindPendingInstance(*instance)) {
305 if (params.url != pending->instance()->url()) {
306 *url_mismatch = true;
307 return;
309 pending->AddRequest(request.Pass());
310 return;
312 scoped_ptr<SharedWorkerPendingInstance> pending_instance(
313 new SharedWorkerPendingInstance(instance.Pass()));
314 pending_instance->AddRequest(request.Pass());
315 ReserveRenderProcessToCreateWorker(pending_instance.Pass(), url_mismatch);
318 void SharedWorkerServiceImpl::ForwardToWorker(
319 const IPC::Message& message,
320 SharedWorkerMessageFilter* filter) {
321 for (WorkerHostMap::const_iterator iter = worker_hosts_.begin();
322 iter != worker_hosts_.end();
323 ++iter) {
324 if (iter->second->FilterMessage(message, filter))
325 return;
329 void SharedWorkerServiceImpl::DocumentDetached(
330 unsigned long long document_id,
331 SharedWorkerMessageFilter* filter) {
332 ScopedWorkerDependencyChecker checker(this);
333 for (WorkerHostMap::const_iterator iter = worker_hosts_.begin();
334 iter != worker_hosts_.end();
335 ++iter) {
336 iter->second->DocumentDetached(filter, document_id);
340 void SharedWorkerServiceImpl::WorkerContextClosed(
341 int worker_route_id,
342 SharedWorkerMessageFilter* filter) {
343 ScopedWorkerDependencyChecker checker(this);
344 if (SharedWorkerHost* host = FindSharedWorkerHost(filter, worker_route_id))
345 host->WorkerContextClosed();
348 void SharedWorkerServiceImpl::WorkerContextDestroyed(
349 int worker_route_id,
350 SharedWorkerMessageFilter* filter) {
351 ScopedWorkerDependencyChecker checker(this);
352 scoped_ptr<SharedWorkerHost> host =
353 worker_hosts_.take_and_erase(std::make_pair(filter->render_process_id(),
354 worker_route_id));
355 if (!host)
356 return;
357 host->WorkerContextDestroyed();
360 void SharedWorkerServiceImpl::WorkerReadyForInspection(
361 int worker_route_id,
362 SharedWorkerMessageFilter* filter) {
363 if (SharedWorkerHost* host = FindSharedWorkerHost(filter, worker_route_id))
364 host->WorkerReadyForInspection();
367 void SharedWorkerServiceImpl::WorkerScriptLoaded(
368 int worker_route_id,
369 SharedWorkerMessageFilter* filter) {
370 if (SharedWorkerHost* host = FindSharedWorkerHost(filter, worker_route_id))
371 host->WorkerScriptLoaded();
374 void SharedWorkerServiceImpl::WorkerScriptLoadFailed(
375 int worker_route_id,
376 SharedWorkerMessageFilter* filter) {
377 ScopedWorkerDependencyChecker checker(this);
378 scoped_ptr<SharedWorkerHost> host =
379 worker_hosts_.take_and_erase(std::make_pair(filter->render_process_id(),
380 worker_route_id));
381 if (!host)
382 return;
383 host->WorkerScriptLoadFailed();
386 void SharedWorkerServiceImpl::WorkerConnected(
387 int message_port_id,
388 int worker_route_id,
389 SharedWorkerMessageFilter* filter) {
390 if (SharedWorkerHost* host = FindSharedWorkerHost(filter, worker_route_id))
391 host->WorkerConnected(message_port_id);
394 void SharedWorkerServiceImpl::AllowDatabase(
395 int worker_route_id,
396 const GURL& url,
397 const base::string16& name,
398 const base::string16& display_name,
399 unsigned long estimated_size,
400 bool* result,
401 SharedWorkerMessageFilter* filter) {
402 if (SharedWorkerHost* host = FindSharedWorkerHost(filter, worker_route_id))
403 host->AllowDatabase(url, name, display_name, estimated_size, result);
404 else
405 *result = false;
408 void SharedWorkerServiceImpl::AllowFileSystem(
409 int worker_route_id,
410 const GURL& url,
411 IPC::Message* reply_msg,
412 SharedWorkerMessageFilter* filter) {
413 if (SharedWorkerHost* host = FindSharedWorkerHost(filter, worker_route_id)) {
414 host->AllowFileSystem(url, make_scoped_ptr(reply_msg));
415 } else {
416 filter->Send(reply_msg);
417 return;
421 void SharedWorkerServiceImpl::AllowIndexedDB(
422 int worker_route_id,
423 const GURL& url,
424 const base::string16& name,
425 bool* result,
426 SharedWorkerMessageFilter* filter) {
427 if (SharedWorkerHost* host = FindSharedWorkerHost(filter, worker_route_id))
428 host->AllowIndexedDB(url, name, result);
429 else
430 *result = false;
433 void SharedWorkerServiceImpl::OnSharedWorkerMessageFilterClosing(
434 SharedWorkerMessageFilter* filter) {
435 ScopedWorkerDependencyChecker checker(this);
436 std::vector<ProcessRouteIdPair> remove_list;
437 for (WorkerHostMap::iterator iter = worker_hosts_.begin();
438 iter != worker_hosts_.end();
439 ++iter) {
440 iter->second->FilterShutdown(filter);
441 if (iter->first.first == filter->render_process_id())
442 remove_list.push_back(iter->first);
444 for (size_t i = 0; i < remove_list.size(); ++i) {
445 scoped_ptr<SharedWorkerHost> host =
446 worker_hosts_.take_and_erase(remove_list[i]);
449 std::vector<int> remove_pending_instance_list;
450 for (PendingInstaneMap::iterator iter = pending_instances_.begin();
451 iter != pending_instances_.end();
452 ++iter) {
453 iter->second->RemoveRequest(filter->render_process_id());
454 if (!iter->second->requests()->size())
455 remove_pending_instance_list.push_back(iter->first);
457 for (size_t i = 0; i < remove_pending_instance_list.size(); ++i)
458 pending_instances_.take_and_erase(remove_pending_instance_list[i]);
461 void SharedWorkerServiceImpl::NotifyWorkerDestroyed(int worker_process_id,
462 int worker_route_id) {
463 FOR_EACH_OBSERVER(WorkerServiceObserver,
464 observers_,
465 WorkerDestroyed(worker_process_id, worker_route_id));
468 void SharedWorkerServiceImpl::ReserveRenderProcessToCreateWorker(
469 scoped_ptr<SharedWorkerPendingInstance> pending_instance,
470 bool* url_mismatch) {
471 DCHECK_CURRENTLY_ON(BrowserThread::IO);
472 DCHECK(!FindPendingInstance(*pending_instance->instance()));
473 if (url_mismatch)
474 *url_mismatch = false;
475 if (!pending_instance->requests()->size())
476 return;
477 int worker_process_id = -1;
478 int worker_route_id = MSG_ROUTING_NONE;
479 bool is_new_worker = true;
480 SharedWorkerHost* host = FindSharedWorkerHost(*pending_instance->instance());
481 if (host) {
482 if (pending_instance->instance()->url() != host->instance()->url()) {
483 if (url_mismatch)
484 *url_mismatch = true;
485 return;
487 worker_process_id = host->process_id();
488 worker_route_id = host->worker_route_id();
489 is_new_worker = false;
490 } else {
491 SharedWorkerMessageFilter* first_filter =
492 (*pending_instance->requests()->begin())->filter;
493 worker_process_id = first_filter->render_process_id();
494 worker_route_id = first_filter->GetNextRoutingID();
496 const int pending_instance_id = next_pending_instance_id_++;
497 scoped_refptr<SharedWorkerReserver> reserver(
498 new SharedWorkerReserver(pending_instance_id,
499 worker_process_id,
500 worker_route_id,
501 is_new_worker,
502 *pending_instance->instance()));
503 BrowserThread::PostTask(
504 BrowserThread::UI,
505 FROM_HERE,
506 base::Bind(
507 &SharedWorkerReserver::TryReserve,
508 reserver,
509 base::Bind(&SharedWorkerServiceImpl::RenderProcessReservedCallback,
510 base::Unretained(this),
511 pending_instance_id,
512 worker_process_id,
513 worker_route_id,
514 is_new_worker),
515 base::Bind(
516 &SharedWorkerServiceImpl::RenderProcessReserveFailedCallback,
517 base::Unretained(this),
518 pending_instance_id,
519 worker_process_id,
520 worker_route_id,
521 is_new_worker),
522 s_try_increment_worker_ref_count_));
523 pending_instances_.set(pending_instance_id, pending_instance.Pass());
526 void SharedWorkerServiceImpl::RenderProcessReservedCallback(
527 int pending_instance_id,
528 int worker_process_id,
529 int worker_route_id,
530 bool is_new_worker,
531 bool pause_on_start) {
532 DCHECK_CURRENTLY_ON(BrowserThread::IO);
533 // To offset the TryIncrementWorkerRefCount called for the reservation,
534 // calls DecrementWorkerRefCount after CheckWorkerDependency in
535 // ScopeWorkerDependencyChecker's destructor.
536 ScopedWorkerDependencyChecker checker(
537 this, base::Bind(&DecrementWorkerRefCount, worker_process_id));
538 scoped_ptr<SharedWorkerPendingInstance> pending_instance =
539 pending_instances_.take_and_erase(pending_instance_id);
540 if (!pending_instance)
541 return;
542 if (!is_new_worker) {
543 SharedWorkerHost* existing_host =
544 worker_hosts_.get(std::make_pair(worker_process_id, worker_route_id));
545 if (!existing_host) {
546 // Retry reserving a renderer process if the existed Shared Worker was
547 // destroyed on IO thread while reserving the renderer process on UI
548 // thread.
549 ReserveRenderProcessToCreateWorker(pending_instance.Pass(), NULL);
550 return;
552 pending_instance->RegisterToSharedWorkerHost(existing_host);
553 pending_instance->SendWorkerCreatedMessages();
554 return;
556 SharedWorkerMessageFilter* filter =
557 pending_instance->FindFilter(worker_process_id);
558 if (!filter) {
559 pending_instance->RemoveRequest(worker_process_id);
560 // Retry reserving a renderer process if the requested renderer process was
561 // destroyed on IO thread while reserving the renderer process on UI thread.
562 ReserveRenderProcessToCreateWorker(pending_instance.Pass(), NULL);
563 return;
565 scoped_ptr<SharedWorkerHost> host(new SharedWorkerHost(
566 pending_instance->release_instance(), filter, worker_route_id));
567 pending_instance->RegisterToSharedWorkerHost(host.get());
568 const GURL url = host->instance()->url();
569 const base::string16 name = host->instance()->name();
570 host->Start(pause_on_start);
571 worker_hosts_.set(std::make_pair(worker_process_id, worker_route_id),
572 host.Pass());
573 FOR_EACH_OBSERVER(
574 WorkerServiceObserver,
575 observers_,
576 WorkerCreated(url, name, worker_process_id, worker_route_id));
579 void SharedWorkerServiceImpl::RenderProcessReserveFailedCallback(
580 int pending_instance_id,
581 int worker_process_id,
582 int worker_route_id,
583 bool is_new_worker) {
584 worker_hosts_.take_and_erase(
585 std::make_pair(worker_process_id, worker_route_id));
586 scoped_ptr<SharedWorkerPendingInstance> pending_instance =
587 pending_instances_.take_and_erase(pending_instance_id);
588 if (!pending_instance)
589 return;
590 pending_instance->RemoveRequest(worker_process_id);
591 // Retry reserving a renderer process.
592 ReserveRenderProcessToCreateWorker(pending_instance.Pass(), NULL);
595 SharedWorkerHost* SharedWorkerServiceImpl::FindSharedWorkerHost(
596 SharedWorkerMessageFilter* filter,
597 int worker_route_id) {
598 return worker_hosts_.get(std::make_pair(filter->render_process_id(),
599 worker_route_id));
602 SharedWorkerHost* SharedWorkerServiceImpl::FindSharedWorkerHost(
603 const SharedWorkerInstance& instance) {
604 for (WorkerHostMap::const_iterator iter = worker_hosts_.begin();
605 iter != worker_hosts_.end();
606 ++iter) {
607 SharedWorkerHost* host = iter->second;
608 if (host->instance() && !host->closed() &&
609 host->instance()->Matches(instance)) {
610 return iter->second;
613 return NULL;
616 SharedWorkerServiceImpl::SharedWorkerPendingInstance*
617 SharedWorkerServiceImpl::FindPendingInstance(
618 const SharedWorkerInstance& instance) {
619 for (PendingInstaneMap::iterator iter = pending_instances_.begin();
620 iter != pending_instances_.end();
621 ++iter) {
622 if (iter->second->instance()->Matches(instance))
623 return iter->second;
625 return NULL;
628 const std::set<int>
629 SharedWorkerServiceImpl::GetRenderersWithWorkerDependency() {
630 std::set<int> dependent_renderers;
631 for (WorkerHostMap::iterator host_iter = worker_hosts_.begin();
632 host_iter != worker_hosts_.end();
633 ++host_iter) {
634 const int process_id = host_iter->first.first;
635 if (dependent_renderers.count(process_id))
636 continue;
637 if (host_iter->second->instance() &&
638 host_iter->second->worker_document_set()->ContainsExternalRenderer(
639 process_id)) {
640 dependent_renderers.insert(process_id);
643 return dependent_renderers;
646 void SharedWorkerServiceImpl::CheckWorkerDependency() {
647 const std::set<int> current_worker_depended_renderers =
648 GetRenderersWithWorkerDependency();
649 std::vector<int> added_items = base::STLSetDifference<std::vector<int> >(
650 current_worker_depended_renderers, last_worker_depended_renderers_);
651 std::vector<int> removed_items = base::STLSetDifference<std::vector<int> >(
652 last_worker_depended_renderers_, current_worker_depended_renderers);
653 if (!added_items.empty() || !removed_items.empty()) {
654 last_worker_depended_renderers_ = current_worker_depended_renderers;
655 update_worker_dependency_(added_items, removed_items);
659 void SharedWorkerServiceImpl::ChangeUpdateWorkerDependencyFuncForTesting(
660 UpdateWorkerDependencyFunc new_func) {
661 update_worker_dependency_ = new_func;
664 void SharedWorkerServiceImpl::ChangeTryIncrementWorkerRefCountFuncForTesting(
665 bool (*new_func)(int)) {
666 s_try_increment_worker_ref_count_ = new_func;
669 } // namespace content