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

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

Issue 14137016: Lower the priority of shared workers (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Moved visible check into worker_service_impl. 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
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"
13 #include "content/browser/worker_host/worker_message_filter.h" 14 #include "content/browser/worker_host/worker_message_filter.h"
14 #include "content/browser/worker_host/worker_process_host.h" 15 #include "content/browser/worker_host/worker_process_host.h"
15 #include "content/common/view_messages.h" 16 #include "content/common/view_messages.h"
16 #include "content/common/worker_messages.h" 17 #include "content/common/worker_messages.h"
17 #include "content/public/browser/child_process_data.h" 18 #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"
18 #include "content/public/browser/resource_context.h" 25 #include "content/public/browser/resource_context.h"
26 #include "content/public/browser/web_contents.h"
19 #include "content/public/browser/worker_service_observer.h" 27 #include "content/public/browser/worker_service_observer.h"
20 #include "content/public/common/content_switches.h" 28 #include "content/public/common/content_switches.h"
21 #include "content/public/common/process_type.h" 29 #include "content/public/common/process_type.h"
22 30
23 namespace content { 31 namespace content {
24 32
25 const int WorkerServiceImpl::kMaxWorkersWhenSeparate = 64; 33 const int WorkerServiceImpl::kMaxWorkersWhenSeparate = 64;
26 const int WorkerServiceImpl::kMaxWorkersPerTabWhenSeparate = 16; 34 const int WorkerServiceImpl::kMaxWorkersPerTabWhenSeparate = 16;
27 35
28 WorkerService* WorkerService::GetInstance() { 36 WorkerService* WorkerService::GetInstance() {
29 return WorkerServiceImpl::GetInstance(); 37 return WorkerServiceImpl::GetInstance();
30 } 38 }
31 39
32 WorkerServiceImpl* WorkerServiceImpl::GetInstance() { 40 WorkerServiceImpl* WorkerServiceImpl::GetInstance() {
33 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 41 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
34 return Singleton<WorkerServiceImpl>::get(); 42 return Singleton<WorkerServiceImpl>::get();
35 } 43 }
36 44
37 WorkerServiceImpl::WorkerServiceImpl() : next_worker_route_id_(0) { 45 WorkerServiceImpl::WorkerServiceImpl()
46 : next_worker_route_id_(0) {
47 BrowserThread::PostTask(
48 BrowserThread::UI, FROM_HERE,
49 base::Bind(&WorkerServiceImpl::RegisterObserver,
50 base::Unretained(this)));
38 } 51 }
39 52
40 WorkerServiceImpl::~WorkerServiceImpl() { 53 WorkerServiceImpl::~WorkerServiceImpl() {
41 // The observers in observers_ can't be used here because they might be 54 // The observers in observers_ can't be used here because they might be
42 // gone already. 55 // gone already.
43 } 56 }
44 57
45 void WorkerServiceImpl::OnWorkerMessageFilterClosing( 58 void WorkerServiceImpl::OnWorkerMessageFilterClosing(
46 WorkerMessageFilter* filter) { 59 WorkerMessageFilter* filter) {
47 for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) { 60 for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) {
(...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after
450 463
451 void WorkerServiceImpl::NotifyWorkerDestroyed( 464 void WorkerServiceImpl::NotifyWorkerDestroyed(
452 WorkerProcessHost* process, 465 WorkerProcessHost* process,
453 int worker_route_id) { 466 int worker_route_id) {
454 WorkerDevToolsManager::GetInstance()->WorkerDestroyed( 467 WorkerDevToolsManager::GetInstance()->WorkerDestroyed(
455 process, worker_route_id); 468 process, worker_route_id);
456 FOR_EACH_OBSERVER(WorkerServiceObserver, observers_, 469 FOR_EACH_OBSERVER(WorkerServiceObserver, observers_,
457 WorkerDestroyed(process->GetData().id, worker_route_id)); 470 WorkerDestroyed(process->GetData().id, worker_route_id));
458 } 471 }
459 472
473 void WorkerServiceImpl::NotifyWorkerProcessCreated() {
474 PostTaskToGatherAndUpdateWorkerPriorities();
475 }
476
460 WorkerProcessHost::WorkerInstance* WorkerServiceImpl::FindSharedWorkerInstance( 477 WorkerProcessHost::WorkerInstance* WorkerServiceImpl::FindSharedWorkerInstance(
461 const GURL& url, 478 const GURL& url,
462 const string16& name, 479 const string16& name,
463 const WorkerStoragePartition& partition, 480 const WorkerStoragePartition& partition,
464 ResourceContext* resource_context) { 481 ResourceContext* resource_context) {
465 for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) { 482 for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) {
466 for (WorkerProcessHost::Instances::iterator instance_iter = 483 for (WorkerProcessHost::Instances::iterator instance_iter =
467 iter->mutable_instances().begin(); 484 iter->mutable_instances().begin();
468 instance_iter != iter->mutable_instances().end(); 485 instance_iter != iter->mutable_instances().end();
469 ++instance_iter) { 486 ++instance_iter) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
519 if (instance) 536 if (instance)
520 return instance; 537 return instance;
521 538
522 // No existing pending worker - create a new one. 539 // No existing pending worker - create a new one.
523 WorkerProcessHost::WorkerInstance pending( 540 WorkerProcessHost::WorkerInstance pending(
524 url, true, name, resource_context, partition); 541 url, true, name, resource_context, partition);
525 pending_shared_workers_.push_back(pending); 542 pending_shared_workers_.push_back(pending);
526 return &pending_shared_workers_.back(); 543 return &pending_shared_workers_.back();
527 } 544 }
528 545
546 void WorkerServiceImpl::RegisterObserver() {
jam 2013/05/09 18:02:57 this class is currently completely on the IO threa
shatch 2013/05/09 22:42:49 Done.
547 registrar_.Add(this, content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED,
jam 2013/05/09 18:02:57 nit: likewise, here and below remove the "content:
shatch 2013/05/09 22:42:49 Done.
548 content::NotificationService::AllBrowserContextsAndSources());
549 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CREATED,
550 content::NotificationService::AllBrowserContextsAndSources());
551 }
552
553 void WorkerServiceImpl::UpdateWorkerPrioritiesFromVisibleSet(
554 const std::set<std::pair<int, int> >* visible_renderer_ids) {
555 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
556
557 for (WorkerProcessHostIterator iter; !iter.Done(); ++iter) {
558 if (!iter->IsProcessLaunched())
559 continue;
560 bool throttle = true;
561
562 for (WorkerProcessHost::Instances::const_iterator instance =
563 iter->instances().begin(); instance != iter->instances().end();
564 ++instance) {
565
566 // This code assumes one worker per process
567 WorkerProcessHost::Instances::const_iterator first_instance =
568 iter->instances().begin();
569 if (first_instance == iter->instances().end())
570 continue;
571
572 WorkerDocumentSet::DocumentInfoSet::const_iterator info =
573 first_instance->worker_document_set()->documents().begin();
574
575 for (; info != first_instance->worker_document_set()->documents().end();
576 ++info) {
577 std::pair<int, int> id(
578 info->render_process_id(), info->render_view_id());
579 if (visible_renderer_ids->find(id) != visible_renderer_ids->end()) {
580 throttle = false;
581 break;
582 }
583 }
584
585 if (!throttle ) {
586 break;
587 }
588 }
589
590 iter->SetBackgrounded(throttle);
591 }
592 }
593
594 void WorkerServiceImpl::OnRenderWidgetVisibilityChanged(
595 std::pair<int, int> id) {
596 std::set<std::pair<int, int> > visible_renderer_ids;
597
598 visible_renderer_ids.insert(id);
599
600 UpdateWorkerPrioritiesFromVisibleSet(&visible_renderer_ids);
601 }
602
603 void WorkerServiceImpl::GatherVisibleIDsAndUpdateWorkerPriorities() {
604 std::set<std::pair<int, int> >* visible_renderer_ids =
605 new std::set<std::pair<int, int> >();
606
607 // Gather up all the visible renderer process/view pairs
608 for (content::RenderProcessHost::iterator it =
609 content::RenderProcessHost::AllHostsIterator();
darin (slow to review) 2013/05/10 23:42:13 nit: like function calls, we usually wrap the line
shatch 2013/05/13 17:47:47 Done.
610 !it.IsAtEnd(); it.Advance()) {
611 content::RenderProcessHost* host = it.GetCurrentValue();
612 if (host->VisibleWidgetCount()) {
613 for (content::RenderProcessHost::RenderWidgetHostsIterator rit =
614 host->GetRenderWidgetHostsIterator(); !rit.IsAtEnd(); rit.Advance()) {
615 content::RenderWidgetHost* widget = host->GetRenderWidgetHostByID(
616 rit.GetCurrentKey());
617 if (widget) {
618 content::RenderWidgetHostView* view = widget->GetView();
619 if (view && view->IsShowing()) {
620 visible_renderer_ids->insert(
621 std::pair<int, int>(host->GetID(),
622 widget->GetRoutingID()));
623 }
624 }
625 }
626 }
627 }
628
629 BrowserThread::PostTask(
630 BrowserThread::IO, FROM_HERE,
631 base::Bind(&WorkerServiceImpl::UpdateWorkerPrioritiesFromVisibleSet,
632 base::Unretained(this),
633 base::Owned(visible_renderer_ids)));
634 }
635
636 void WorkerServiceImpl::PostTaskToGatherAndUpdateWorkerPriorities() {
637 BrowserThread::PostTask(
638 BrowserThread::UI, FROM_HERE,
639 base::Bind(
640 &WorkerServiceImpl::GatherVisibleIDsAndUpdateWorkerPriorities,
641 base::Unretained(this)));
642 }
643
644 void WorkerServiceImpl::Observe(int type,
645 const NotificationSource& source,
646 const NotificationDetails& details) {
647 if (type == content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED) {
648 bool visible = *content::Details<bool>(details).ptr();
649
650 if (visible) {
651 int id = content::Source<content::RenderWidgetHost>(source).ptr()->
jam 2013/05/09 18:02:57 nit: naming wise, convention is render_view_id ren
shatch 2013/05/09 22:42:49 Done.
652 GetRoutingID();
653 int pid = content::Source<content::RenderWidgetHost>(source).ptr()->
654 GetProcess()->GetID();
655
656 BrowserThread::PostTask(
657 BrowserThread::IO, FROM_HERE,
658 base::Bind(&WorkerServiceImpl::OnRenderWidgetVisibilityChanged,
659 base::Unretained(this),
660 std::pair<int, int>(pid, id)));
661 }
662 }
663 else if (type == NOTIFICATION_RENDERER_PROCESS_CREATED) {
664 PostTaskToGatherAndUpdateWorkerPriorities();
665 }
666 }
667
529 } // namespace content 668 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698