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

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

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

Powered by Google App Engine
This is Rietveld 408576698