Battery Status API: add UMA logging for Linux.
[chromium-blink-merge.git] / content / browser / shared_worker / shared_worker_service_impl.cc
blobb773127db631cf5b2b7e439452e17d3eb35b3437
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/embedded_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(BrowserThread::CurrentlyOn(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 EmbeddedWorkerDevToolsManager::GetInstance()->SharedWorkerCreated(
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(BrowserThread::CurrentlyOn(BrowserThread::IO));
224 return 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(BrowserThread::CurrentlyOn(BrowserThread::IO));
273 observers_.AddObserver(observer);
276 void SharedWorkerServiceImpl::RemoveObserver(WorkerServiceObserver* observer) {
277 DCHECK(BrowserThread::CurrentlyOn(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(BrowserThread::CurrentlyOn(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);
406 void SharedWorkerServiceImpl::AllowFileSystem(
407 int worker_route_id,
408 const GURL& url,
409 IPC::Message* reply_msg,
410 SharedWorkerMessageFilter* filter) {
411 if (SharedWorkerHost* host = FindSharedWorkerHost(filter, worker_route_id)) {
412 host->AllowFileSystem(url, make_scoped_ptr(reply_msg));
413 } else {
414 filter->Send(reply_msg);
415 return;
419 void SharedWorkerServiceImpl::AllowIndexedDB(
420 int worker_route_id,
421 const GURL& url,
422 const base::string16& name,
423 bool* result,
424 SharedWorkerMessageFilter* filter) {
425 if (SharedWorkerHost* host = FindSharedWorkerHost(filter, worker_route_id))
426 host->AllowIndexedDB(url, name, result);
429 void SharedWorkerServiceImpl::OnSharedWorkerMessageFilterClosing(
430 SharedWorkerMessageFilter* filter) {
431 ScopedWorkerDependencyChecker checker(this);
432 std::vector<ProcessRouteIdPair> remove_list;
433 for (WorkerHostMap::iterator iter = worker_hosts_.begin();
434 iter != worker_hosts_.end();
435 ++iter) {
436 iter->second->FilterShutdown(filter);
437 if (iter->first.first == filter->render_process_id())
438 remove_list.push_back(iter->first);
440 for (size_t i = 0; i < remove_list.size(); ++i) {
441 scoped_ptr<SharedWorkerHost> host =
442 worker_hosts_.take_and_erase(remove_list[i]);
445 std::vector<int> remove_pending_instance_list;
446 for (PendingInstaneMap::iterator iter = pending_instances_.begin();
447 iter != pending_instances_.end();
448 ++iter) {
449 iter->second->RemoveRequest(filter->render_process_id());
450 if (!iter->second->requests()->size())
451 remove_pending_instance_list.push_back(iter->first);
453 for (size_t i = 0; i < remove_pending_instance_list.size(); ++i)
454 pending_instances_.take_and_erase(remove_pending_instance_list[i]);
457 void SharedWorkerServiceImpl::NotifyWorkerDestroyed(int worker_process_id,
458 int worker_route_id) {
459 FOR_EACH_OBSERVER(WorkerServiceObserver,
460 observers_,
461 WorkerDestroyed(worker_process_id, worker_route_id));
464 void SharedWorkerServiceImpl::ReserveRenderProcessToCreateWorker(
465 scoped_ptr<SharedWorkerPendingInstance> pending_instance,
466 bool* url_mismatch) {
467 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
468 DCHECK(!FindPendingInstance(*pending_instance->instance()));
469 if (url_mismatch)
470 *url_mismatch = false;
471 if (!pending_instance->requests()->size())
472 return;
473 int worker_process_id = -1;
474 int worker_route_id = MSG_ROUTING_NONE;
475 bool is_new_worker = true;
476 SharedWorkerHost* host = FindSharedWorkerHost(*pending_instance->instance());
477 if (host) {
478 if (pending_instance->instance()->url() != host->instance()->url()) {
479 if (url_mismatch)
480 *url_mismatch = true;
481 return;
483 worker_process_id = host->process_id();
484 worker_route_id = host->worker_route_id();
485 is_new_worker = false;
486 } else {
487 SharedWorkerMessageFilter* first_filter =
488 (*pending_instance->requests()->begin())->filter;
489 worker_process_id = first_filter->render_process_id();
490 worker_route_id = first_filter->GetNextRoutingID();
492 const int pending_instance_id = next_pending_instance_id_++;
493 scoped_refptr<SharedWorkerReserver> reserver(
494 new SharedWorkerReserver(pending_instance_id,
495 worker_process_id,
496 worker_route_id,
497 is_new_worker,
498 *pending_instance->instance()));
499 BrowserThread::PostTask(
500 BrowserThread::UI,
501 FROM_HERE,
502 base::Bind(
503 &SharedWorkerReserver::TryReserve,
504 reserver,
505 base::Bind(&SharedWorkerServiceImpl::RenderProcessReservedCallback,
506 base::Unretained(this),
507 pending_instance_id,
508 worker_process_id,
509 worker_route_id,
510 is_new_worker),
511 base::Bind(
512 &SharedWorkerServiceImpl::RenderProcessReserveFailedCallback,
513 base::Unretained(this),
514 pending_instance_id,
515 worker_process_id,
516 worker_route_id,
517 is_new_worker),
518 s_try_increment_worker_ref_count_));
519 pending_instances_.set(pending_instance_id, pending_instance.Pass());
522 void SharedWorkerServiceImpl::RenderProcessReservedCallback(
523 int pending_instance_id,
524 int worker_process_id,
525 int worker_route_id,
526 bool is_new_worker,
527 bool pause_on_start) {
528 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
529 // To offset the TryIncrementWorkerRefCount called for the reservation,
530 // calls DecrementWorkerRefCount after CheckWorkerDependency in
531 // ScopeWorkerDependencyChecker's destructor.
532 ScopedWorkerDependencyChecker checker(
533 this, base::Bind(&DecrementWorkerRefCount, worker_process_id));
534 scoped_ptr<SharedWorkerPendingInstance> pending_instance =
535 pending_instances_.take_and_erase(pending_instance_id);
536 if (!pending_instance)
537 return;
538 if (!is_new_worker) {
539 SharedWorkerHost* existing_host =
540 worker_hosts_.get(std::make_pair(worker_process_id, worker_route_id));
541 if (!existing_host) {
542 // Retry reserving a renderer process if the existed Shared Worker was
543 // destroyed on IO thread while reserving the renderer process on UI
544 // thread.
545 ReserveRenderProcessToCreateWorker(pending_instance.Pass(), NULL);
546 return;
548 pending_instance->RegisterToSharedWorkerHost(existing_host);
549 pending_instance->SendWorkerCreatedMessages();
550 return;
552 SharedWorkerMessageFilter* filter =
553 pending_instance->FindFilter(worker_process_id);
554 if (!filter) {
555 pending_instance->RemoveRequest(worker_process_id);
556 // Retry reserving a renderer process if the requested renderer process was
557 // destroyed on IO thread while reserving the renderer process on UI thread.
558 ReserveRenderProcessToCreateWorker(pending_instance.Pass(), NULL);
559 return;
561 scoped_ptr<SharedWorkerHost> host(new SharedWorkerHost(
562 pending_instance->release_instance(), filter, worker_route_id));
563 pending_instance->RegisterToSharedWorkerHost(host.get());
564 const GURL url = host->instance()->url();
565 const base::string16 name = host->instance()->name();
566 host->Start(pause_on_start);
567 worker_hosts_.set(std::make_pair(worker_process_id, worker_route_id),
568 host.Pass());
569 FOR_EACH_OBSERVER(
570 WorkerServiceObserver,
571 observers_,
572 WorkerCreated(url, name, worker_process_id, worker_route_id));
575 void SharedWorkerServiceImpl::RenderProcessReserveFailedCallback(
576 int pending_instance_id,
577 int worker_process_id,
578 int worker_route_id,
579 bool is_new_worker) {
580 worker_hosts_.take_and_erase(
581 std::make_pair(worker_process_id, worker_route_id));
582 scoped_ptr<SharedWorkerPendingInstance> pending_instance =
583 pending_instances_.take_and_erase(pending_instance_id);
584 if (!pending_instance)
585 return;
586 pending_instance->RemoveRequest(worker_process_id);
587 // Retry reserving a renderer process.
588 ReserveRenderProcessToCreateWorker(pending_instance.Pass(), NULL);
591 SharedWorkerHost* SharedWorkerServiceImpl::FindSharedWorkerHost(
592 SharedWorkerMessageFilter* filter,
593 int worker_route_id) {
594 return worker_hosts_.get(std::make_pair(filter->render_process_id(),
595 worker_route_id));
598 SharedWorkerHost* SharedWorkerServiceImpl::FindSharedWorkerHost(
599 const SharedWorkerInstance& instance) {
600 for (WorkerHostMap::const_iterator iter = worker_hosts_.begin();
601 iter != worker_hosts_.end();
602 ++iter) {
603 SharedWorkerHost* host = iter->second;
604 if (host->instance() && !host->closed() &&
605 host->instance()->Matches(instance)) {
606 return iter->second;
609 return NULL;
612 SharedWorkerServiceImpl::SharedWorkerPendingInstance*
613 SharedWorkerServiceImpl::FindPendingInstance(
614 const SharedWorkerInstance& instance) {
615 for (PendingInstaneMap::iterator iter = pending_instances_.begin();
616 iter != pending_instances_.end();
617 ++iter) {
618 if (iter->second->instance()->Matches(instance))
619 return iter->second;
621 return NULL;
624 const std::set<int>
625 SharedWorkerServiceImpl::GetRenderersWithWorkerDependency() {
626 std::set<int> dependent_renderers;
627 for (WorkerHostMap::iterator host_iter = worker_hosts_.begin();
628 host_iter != worker_hosts_.end();
629 ++host_iter) {
630 const int process_id = host_iter->first.first;
631 if (dependent_renderers.count(process_id))
632 continue;
633 if (host_iter->second->instance() &&
634 host_iter->second->worker_document_set()->ContainsExternalRenderer(
635 process_id)) {
636 dependent_renderers.insert(process_id);
639 return dependent_renderers;
642 void SharedWorkerServiceImpl::CheckWorkerDependency() {
643 const std::set<int> current_worker_depended_renderers =
644 GetRenderersWithWorkerDependency();
645 std::vector<int> added_items = base::STLSetDifference<std::vector<int> >(
646 current_worker_depended_renderers, last_worker_depended_renderers_);
647 std::vector<int> removed_items = base::STLSetDifference<std::vector<int> >(
648 last_worker_depended_renderers_, current_worker_depended_renderers);
649 if (!added_items.empty() || !removed_items.empty()) {
650 last_worker_depended_renderers_ = current_worker_depended_renderers;
651 update_worker_dependency_(added_items, removed_items);
655 void SharedWorkerServiceImpl::ChangeUpdateWorkerDependencyFuncForTesting(
656 UpdateWorkerDependencyFunc new_func) {
657 update_worker_dependency_ = new_func;
660 void SharedWorkerServiceImpl::ChangeTryIncrementWorkerRefCountFuncForTesting(
661 bool (*new_func)(int)) {
662 s_try_increment_worker_ref_count_ = new_func;
665 } // namespace content