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

Side by Side Diff: extensions/browser/process_manager.cc

Issue 2762513002: Remove keep-alive impulse IPCs from NaCl modules. (Closed)
Patch Set: Created 3 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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "extensions/browser/process_manager.h" 5 #include "extensions/browser/process_manager.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/location.h" 10 #include "base/location.h"
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 114
115 void PropagateExtensionWakeResult(const base::Callback<void(bool)>& callback, 115 void PropagateExtensionWakeResult(const base::Callback<void(bool)>& callback,
116 extensions::ExtensionHost* host) { 116 extensions::ExtensionHost* host) {
117 callback.Run(host != nullptr); 117 callback.Run(host != nullptr);
118 } 118 }
119 119
120 } // namespace 120 } // namespace
121 121
122 struct ProcessManager::BackgroundPageData { 122 struct ProcessManager::BackgroundPageData {
123 // The count of things keeping the lazy background page alive. 123 // The count of things keeping the lazy background page alive.
124 int lazy_keepalive_count; 124 int lazy_keepalive_count = 0;
125
126 // Tracks if an impulse event has occured since the last polling check.
127 bool keepalive_impulse;
128 bool previous_keepalive_impulse;
129 125
130 // True if the page responded to the ShouldSuspend message and is currently 126 // True if the page responded to the ShouldSuspend message and is currently
131 // dispatching the suspend event. During this time any events that arrive will 127 // dispatching the suspend event. During this time any events that arrive will
132 // cancel the suspend process and an onSuspendCanceled event will be 128 // cancel the suspend process and an onSuspendCanceled event will be
133 // dispatched to the page. 129 // dispatched to the page.
134 bool is_closing; 130 bool is_closing = false;
135 131
136 // Stores the value of the incremented 132 // Stores the value of the incremented
137 // ProcessManager::last_background_close_sequence_id_ whenever the extension 133 // ProcessManager::last_background_close_sequence_id_ whenever the extension
138 // is active. A copy of the ID is also passed in the callbacks and IPC 134 // is active. A copy of the ID is also passed in the callbacks and IPC
139 // messages leading up to CloseLazyBackgroundPageNow. The process is aborted 135 // messages leading up to CloseLazyBackgroundPageNow. The process is aborted
140 // if the IDs ever differ due to new activity. 136 // if the IDs ever differ due to new activity.
141 uint64_t close_sequence_id; 137 uint64_t close_sequence_id = 0ull;
142 138
143 // Keeps track of when this page was last suspended. Used for perf metrics. 139 // Keeps track of when this page was last suspended. Used for perf metrics.
144 std::unique_ptr<base::ElapsedTimer> since_suspended; 140 std::unique_ptr<base::ElapsedTimer> since_suspended;
145
146 BackgroundPageData()
147 : lazy_keepalive_count(0),
148 keepalive_impulse(false),
149 previous_keepalive_impulse(false),
150 is_closing(false),
151 close_sequence_id(0) {}
152 }; 141 };
153 142
154 // Data of a RenderFrameHost associated with an extension. 143 // Data of a RenderFrameHost associated with an extension.
155 struct ProcessManager::ExtensionRenderFrameData { 144 struct ProcessManager::ExtensionRenderFrameData {
156 // The type of the view. 145 // The type of the view.
157 extensions::ViewType view_type; 146 extensions::ViewType view_type = VIEW_TYPE_INVALID;
158 147
159 // Whether the view is keeping the lazy background page alive or not. 148 // Whether the view is keeping the lazy background page alive or not.
160 bool has_keepalive; 149 bool has_keepalive = false;
161
162 ExtensionRenderFrameData()
163 : view_type(VIEW_TYPE_INVALID), has_keepalive(false) {}
164 150
165 // Returns whether the view can keep the lazy background page alive or not. 151 // Returns whether the view can keep the lazy background page alive or not.
166 bool CanKeepalive() const { 152 bool CanKeepalive() const {
167 switch (view_type) { 153 switch (view_type) {
168 case VIEW_TYPE_APP_WINDOW: 154 case VIEW_TYPE_APP_WINDOW:
169 case VIEW_TYPE_BACKGROUND_CONTENTS: 155 case VIEW_TYPE_BACKGROUND_CONTENTS:
170 case VIEW_TYPE_COMPONENT: 156 case VIEW_TYPE_COMPONENT:
171 case VIEW_TYPE_EXTENSION_DIALOG: 157 case VIEW_TYPE_EXTENSION_DIALOG:
172 case VIEW_TYPE_EXTENSION_GUEST: 158 case VIEW_TYPE_EXTENSION_GUEST:
173 case VIEW_TYPE_EXTENSION_POPUP: 159 case VIEW_TYPE_EXTENSION_POPUP:
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED, 242 extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED,
257 content::Source<BrowserContext>(original_context)); 243 content::Source<BrowserContext>(original_context));
258 } 244 }
259 registrar_.Add(this, 245 registrar_.Add(this,
260 extensions::NOTIFICATION_EXTENSION_HOST_DESTROYED, 246 extensions::NOTIFICATION_EXTENSION_HOST_DESTROYED,
261 content::Source<BrowserContext>(context)); 247 content::Source<BrowserContext>(context));
262 registrar_.Add(this, 248 registrar_.Add(this,
263 extensions::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE, 249 extensions::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE,
264 content::Source<BrowserContext>(context)); 250 content::Source<BrowserContext>(context));
265 content::DevToolsAgentHost::AddObserver(this); 251 content::DevToolsAgentHost::AddObserver(this);
266
267 OnKeepaliveImpulseCheck();
268 } 252 }
269 253
270 ProcessManager::~ProcessManager() { 254 ProcessManager::~ProcessManager() {
271 extension_registry_->RemoveObserver(this); 255 extension_registry_->RemoveObserver(this);
272 CloseBackgroundHosts(); 256 CloseBackgroundHosts();
273 DCHECK(background_hosts_.empty()); 257 DCHECK(background_hosts_.empty());
274 content::DevToolsAgentHost::RemoveObserver(this); 258 content::DevToolsAgentHost::RemoveObserver(this);
275 } 259 }
276 260
277 void ProcessManager::RegisterRenderFrameHost( 261 void ProcessManager::RegisterRenderFrameHost(
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
483 if (++count == 1) 467 if (++count == 1)
484 OnLazyBackgroundPageActive(extension->id()); 468 OnLazyBackgroundPageActive(extension->id());
485 } 469 }
486 } 470 }
487 471
488 void ProcessManager::DecrementLazyKeepaliveCount(const Extension* extension) { 472 void ProcessManager::DecrementLazyKeepaliveCount(const Extension* extension) {
489 if (BackgroundInfo::HasLazyBackgroundPage(extension)) 473 if (BackgroundInfo::HasLazyBackgroundPage(extension))
490 DecrementLazyKeepaliveCount(extension->id()); 474 DecrementLazyKeepaliveCount(extension->id());
491 } 475 }
492 476
493 // This implementation layers on top of the keepalive count. An impulse sets
494 // a per extension flag. On a regular interval that flag is checked. Changes
495 // from the flag not being set to set cause an IncrementLazyKeepaliveCount.
496 void ProcessManager::KeepaliveImpulse(const Extension* extension) {
497 if (!BackgroundInfo::HasLazyBackgroundPage(extension))
498 return;
499
500 BackgroundPageData& bd = background_page_data_[extension->id()];
501
502 if (!bd.keepalive_impulse) {
503 bd.keepalive_impulse = true;
504 if (!bd.previous_keepalive_impulse) {
505 IncrementLazyKeepaliveCount(extension);
506 }
507 }
508
509 if (!keepalive_impulse_callback_for_testing_.is_null()) {
510 ImpulseCallbackForTesting callback_may_clear_callbacks_reentrantly =
511 keepalive_impulse_callback_for_testing_;
512 callback_may_clear_callbacks_reentrantly.Run(extension->id());
513 }
514 }
515
516 // static
517 void ProcessManager::OnKeepaliveFromPlugin(int render_process_id,
518 int render_frame_id,
519 const std::string& extension_id) {
520 content::RenderFrameHost* render_frame_host =
521 content::RenderFrameHost::FromID(render_process_id, render_frame_id);
522 if (!render_frame_host)
523 return;
524
525 content::SiteInstance* site_instance = render_frame_host->GetSiteInstance();
526 if (!site_instance)
527 return;
528
529 BrowserContext* browser_context = site_instance->GetBrowserContext();
530 const Extension* extension =
531 ExtensionRegistry::Get(browser_context)->enabled_extensions().GetByID(
532 extension_id);
533 if (!extension)
534 return;
535
536 ProcessManager::Get(browser_context)->KeepaliveImpulse(extension);
537 }
538
539 void ProcessManager::OnShouldSuspendAck(const std::string& extension_id, 477 void ProcessManager::OnShouldSuspendAck(const std::string& extension_id,
540 uint64_t sequence_id) { 478 uint64_t sequence_id) {
541 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); 479 ExtensionHost* host = GetBackgroundHostForExtension(extension_id);
542 if (host && 480 if (host &&
543 sequence_id == background_page_data_[extension_id].close_sequence_id) { 481 sequence_id == background_page_data_[extension_id].close_sequence_id) {
544 host->render_process_host()->Send(new ExtensionMsg_Suspend(extension_id)); 482 host->render_process_host()->Send(new ExtensionMsg_Suspend(extension_id));
545 } 483 }
546 } 484 }
547 485
548 void ProcessManager::OnSuspendAck(const std::string& extension_id) { 486 void ProcessManager::OnSuspendAck(const std::string& extension_id) {
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
618 // which will cause the removal of the host from the |background_hosts_| set 556 // which will cause the removal of the host from the |background_hosts_| set
619 // in the Observe() method below. 557 // in the Observe() method below.
620 delete host; 558 delete host;
621 DCHECK_EQ(0u, background_hosts_.count(host)); 559 DCHECK_EQ(0u, background_hosts_.count(host));
622 } 560 }
623 561
624 // At this point there should be nothing left in |background_hosts_|. 562 // At this point there should be nothing left in |background_hosts_|.
625 DCHECK(background_hosts_.empty()); 563 DCHECK(background_hosts_.empty());
626 } 564 }
627 565
628 void ProcessManager::SetKeepaliveImpulseCallbackForTesting(
629 const ImpulseCallbackForTesting& callback) {
630 keepalive_impulse_callback_for_testing_ = callback;
631 }
632
633 void ProcessManager::SetKeepaliveImpulseDecrementCallbackForTesting(
634 const ImpulseCallbackForTesting& callback) {
635 keepalive_impulse_decrement_callback_for_testing_ = callback;
636 }
637
638 // static 566 // static
639 void ProcessManager::SetEventPageIdleTimeForTesting(unsigned idle_time_msec) { 567 void ProcessManager::SetEventPageIdleTimeForTesting(unsigned idle_time_msec) {
640 CHECK_GT(idle_time_msec, 0u); // OnKeepaliveImpulseCheck requires non zero. 568 CHECK_GT(idle_time_msec, 0u); // OnKeepaliveImpulseCheck requires non zero.
Devlin 2017/03/21 01:08:15 OnKeepaliveImpulseCheck() no longer exists
Wez 2017/03/21 23:59:22 Done.
641 g_event_page_idle_time_msec = idle_time_msec; 569 g_event_page_idle_time_msec = idle_time_msec;
642 } 570 }
643 571
644 // static 572 // static
645 void ProcessManager::SetEventPageSuspendingTimeForTesting( 573 void ProcessManager::SetEventPageSuspendingTimeForTesting(
646 unsigned suspending_time_msec) { 574 unsigned suspending_time_msec) {
647 g_event_page_suspending_time_msec = suspending_time_msec; 575 g_event_page_suspending_time_msec = suspending_time_msec;
648 } 576 }
649 577
650 //////////////////////////////////////////////////////////////////////////////// 578 ////////////////////////////////////////////////////////////////////////////////
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
788 background_page_data_[extension_id].close_sequence_id = 716 background_page_data_[extension_id].close_sequence_id =
789 ++last_background_close_sequence_id_; 717 ++last_background_close_sequence_id_;
790 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( 718 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
791 FROM_HERE, base::Bind(&ProcessManager::OnLazyBackgroundPageIdle, 719 FROM_HERE, base::Bind(&ProcessManager::OnLazyBackgroundPageIdle,
792 weak_ptr_factory_.GetWeakPtr(), extension_id, 720 weak_ptr_factory_.GetWeakPtr(), extension_id,
793 last_background_close_sequence_id_), 721 last_background_close_sequence_id_),
794 base::TimeDelta::FromMilliseconds(g_event_page_idle_time_msec)); 722 base::TimeDelta::FromMilliseconds(g_event_page_idle_time_msec));
795 } 723 }
796 } 724 }
797 725
798 // DecrementLazyKeepaliveCount is called when no calls to KeepaliveImpulse
799 // have been made for at least g_event_page_idle_time_msec. In the best case an
800 // impulse was made just before being cleared, and the decrement will occur
801 // g_event_page_idle_time_msec later, causing a 2 * g_event_page_idle_time_msec
802 // total time for extension to be shut down based on impulses. Worst case is
803 // an impulse just after a clear, adding one check cycle and resulting in 3x
804 // total time.
805 void ProcessManager::OnKeepaliveImpulseCheck() {
806 for (BackgroundPageDataMap::iterator i = background_page_data_.begin();
807 i != background_page_data_.end();
808 ++i) {
809 if (i->second.previous_keepalive_impulse && !i->second.keepalive_impulse) {
810 DecrementLazyKeepaliveCount(i->first);
811 if (!keepalive_impulse_decrement_callback_for_testing_.is_null()) {
812 ImpulseCallbackForTesting callback_may_clear_callbacks_reentrantly =
813 keepalive_impulse_decrement_callback_for_testing_;
814 callback_may_clear_callbacks_reentrantly.Run(i->first);
815 }
816 }
817
818 i->second.previous_keepalive_impulse = i->second.keepalive_impulse;
819 i->second.keepalive_impulse = false;
820 }
821
822 // OnKeepaliveImpulseCheck() is always called in constructor, but in unit
823 // tests there will be no thread task runner handle. In that event don't
824 // schedule tasks.
825 if (base::ThreadTaskRunnerHandle::IsSet()) {
826 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
827 FROM_HERE, base::Bind(&ProcessManager::OnKeepaliveImpulseCheck,
828 weak_ptr_factory_.GetWeakPtr()),
829 base::TimeDelta::FromMilliseconds(g_event_page_idle_time_msec));
830 }
831 }
832
833 void ProcessManager::OnLazyBackgroundPageIdle(const std::string& extension_id, 726 void ProcessManager::OnLazyBackgroundPageIdle(const std::string& extension_id,
834 uint64_t sequence_id) { 727 uint64_t sequence_id) {
835 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); 728 ExtensionHost* host = GetBackgroundHostForExtension(extension_id);
836 if (host && !background_page_data_[extension_id].is_closing && 729 if (host && !background_page_data_[extension_id].is_closing &&
837 sequence_id == background_page_data_[extension_id].close_sequence_id) { 730 sequence_id == background_page_data_[extension_id].close_sequence_id) {
838 // Tell the renderer we are about to close. This is a simple ping that the 731 // Tell the renderer we are about to close. This is a simple ping that the
839 // renderer will respond to. The purpose is to control sequencing: if the 732 // renderer will respond to. The purpose is to control sequencing: if the
840 // extension remains idle until the renderer responds with an ACK, then we 733 // extension remains idle until the renderer responds with an ACK, then we
841 // know that the extension process is ready to shut down. If our 734 // know that the extension process is ready to shut down. If our
842 // close_sequence_id has already changed, then we would ignore the 735 // close_sequence_id has already changed, then we would ignore the
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
990 if (extension && !IncognitoInfo::IsSplitMode(extension)) { 883 if (extension && !IncognitoInfo::IsSplitMode(extension)) {
991 BrowserContext* original_context = 884 BrowserContext* original_context =
992 ExtensionsBrowserClient::Get()->GetOriginalContext(browser_context()); 885 ExtensionsBrowserClient::Get()->GetOriginalContext(browser_context());
993 return ProcessManager::Get(original_context)->GetSiteInstanceForURL(url); 886 return ProcessManager::Get(original_context)->GetSiteInstanceForURL(url);
994 } 887 }
995 888
996 return ProcessManager::GetSiteInstanceForURL(url); 889 return ProcessManager::GetSiteInstanceForURL(url);
997 } 890 }
998 891
999 } // namespace extensions 892 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698