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

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

Issue 60613004: Add KeepaliveImpulse to extension process manager. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « extensions/browser/process_manager.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "base/bind.h" 7 #include "base/bind.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/lazy_instance.h" 9 #include "base/lazy_instance.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 130
131 ProcessManager* process_manager_; 131 ProcessManager* process_manager_;
132 132
133 DISALLOW_COPY_AND_ASSIGN(RenderViewHostDestructionObserver); 133 DISALLOW_COPY_AND_ASSIGN(RenderViewHostDestructionObserver);
134 }; 134 };
135 135
136 struct ProcessManager::BackgroundPageData { 136 struct ProcessManager::BackgroundPageData {
137 // The count of things keeping the lazy background page alive. 137 // The count of things keeping the lazy background page alive.
138 int lazy_keepalive_count; 138 int lazy_keepalive_count;
139 139
140 // Tracks if an impulse event has occured since the last polling check.
141 bool keepalive_impulse;
142 bool previous_keepalive_impulse;
143
140 // This is used with the ShouldSuspend message, to ensure that the extension 144 // This is used with the ShouldSuspend message, to ensure that the extension
141 // remained idle between sending the message and receiving the ack. 145 // remained idle between sending the message and receiving the ack.
142 int close_sequence_id; 146 int close_sequence_id;
143 147
144 // True if the page responded to the ShouldSuspend message and is currently 148 // True if the page responded to the ShouldSuspend message and is currently
145 // dispatching the suspend event. During this time any events that arrive will 149 // dispatching the suspend event. During this time any events that arrive will
146 // cancel the suspend process and an onSuspendCanceled event will be 150 // cancel the suspend process and an onSuspendCanceled event will be
147 // dispatched to the page. 151 // dispatched to the page.
148 bool is_closing; 152 bool is_closing;
149 153
150 // Keeps track of when this page was last suspended. Used for perf metrics. 154 // Keeps track of when this page was last suspended. Used for perf metrics.
151 linked_ptr<base::ElapsedTimer> since_suspended; 155 linked_ptr<base::ElapsedTimer> since_suspended;
152 156
153 BackgroundPageData() 157 BackgroundPageData()
154 : lazy_keepalive_count(0), close_sequence_id(0), is_closing(false) {} 158 : lazy_keepalive_count(0),
159 keepalive_impulse(false),
160 previous_keepalive_impulse(false),
161 close_sequence_id(0),
162 is_closing(false) {}
155 }; 163 };
156 164
157 // 165 //
158 // ProcessManager 166 // ProcessManager
159 // 167 //
160 168
161 // static 169 // static
162 ProcessManager* ProcessManager::Create(BrowserContext* context) { 170 ProcessManager* ProcessManager::Create(BrowserContext* context) {
163 if (context->IsOffTheRecord()) { 171 if (context->IsOffTheRecord()) {
164 BrowserContext* original_context = 172 BrowserContext* original_context =
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 unsigned suspending_time_sec = 0; 218 unsigned suspending_time_sec = 0;
211 if (base::StringToUint(CommandLine::ForCurrentProcess()->GetSwitchValueASCII( 219 if (base::StringToUint(CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
212 extensions::switches::kEventPageSuspendingTime), 220 extensions::switches::kEventPageSuspendingTime),
213 &suspending_time_sec)) { 221 &suspending_time_sec)) {
214 event_page_suspending_time_ = 222 event_page_suspending_time_ =
215 base::TimeDelta::FromSeconds(suspending_time_sec); 223 base::TimeDelta::FromSeconds(suspending_time_sec);
216 } 224 }
217 225
218 content::DevToolsManager::GetInstance()->AddAgentStateCallback( 226 content::DevToolsManager::GetInstance()->AddAgentStateCallback(
219 devtools_callback_); 227 devtools_callback_);
228
229 OnKeepaliveImpulseCheck();
220 } 230 }
221 231
222 ProcessManager::~ProcessManager() { 232 ProcessManager::~ProcessManager() {
223 CloseBackgroundHosts(); 233 CloseBackgroundHosts();
224 DCHECK(background_hosts_.empty()); 234 DCHECK(background_hosts_.empty());
225 content::DevToolsManager::GetInstance()->RemoveAgentStateCallback( 235 content::DevToolsManager::GetInstance()->RemoveAgentStateCallback(
226 devtools_callback_); 236 devtools_callback_);
227 } 237 }
228 238
229 const ProcessManager::ViewSet ProcessManager::GetAllViews() const { 239 const ProcessManager::ViewSet ProcessManager::GetAllViews() const {
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 int& count = background_page_data_[extension->id()].lazy_keepalive_count; 375 int& count = background_page_data_[extension->id()].lazy_keepalive_count;
366 if (++count == 1) 376 if (++count == 1)
367 OnLazyBackgroundPageActive(extension->id()); 377 OnLazyBackgroundPageActive(extension->id());
368 378
369 return count; 379 return count;
370 } 380 }
371 381
372 int ProcessManager::DecrementLazyKeepaliveCount(const Extension* extension) { 382 int ProcessManager::DecrementLazyKeepaliveCount(const Extension* extension) {
373 if (!BackgroundInfo::HasLazyBackgroundPage(extension)) 383 if (!BackgroundInfo::HasLazyBackgroundPage(extension))
374 return 0; 384 return 0;
385 return DecrementLazyKeepaliveCountById(extension->id());
386 }
375 387
376 int& count = background_page_data_[extension->id()].lazy_keepalive_count; 388 int ProcessManager::DecrementLazyKeepaliveCountById(std::string extension_id) {
Matt Perry 2013/11/19 21:35:08 nit: I think this is similar enough to DecrementLa
scheib 2013/11/19 23:18:25 Done.
389 int& count = background_page_data_[extension_id].lazy_keepalive_count;
377 DCHECK_GT(count, 0); 390 DCHECK_GT(count, 0);
378 391
379 // If we reach a zero keepalive count when the lazy background page is about 392 // If we reach a zero keepalive count when the lazy background page is about
380 // to be closed, incrementing close_sequence_id will cancel the close 393 // to be closed, incrementing close_sequence_id will cancel the close
381 // sequence and cause the background page to linger. So check is_closing 394 // sequence and cause the background page to linger. So check is_closing
382 // before initiating another close sequence. 395 // before initiating another close sequence.
383 if (--count == 0 && !background_page_data_[extension->id()].is_closing) { 396 if (--count == 0 && !background_page_data_[extension_id].is_closing) {
384 base::MessageLoop::current()->PostDelayedTask( 397 base::MessageLoop::current()->PostDelayedTask(
385 FROM_HERE, 398 FROM_HERE,
386 base::Bind(&ProcessManager::OnLazyBackgroundPageIdle, 399 base::Bind(&ProcessManager::OnLazyBackgroundPageIdle,
387 weak_ptr_factory_.GetWeakPtr(), extension->id(), 400 weak_ptr_factory_.GetWeakPtr(), extension_id,
388 ++background_page_data_[extension->id()].close_sequence_id), 401 ++background_page_data_[extension_id].close_sequence_id),
389 event_page_idle_time_); 402 event_page_idle_time_);
390 } 403 }
391 404
392 return count; 405 return count;
393 } 406 }
394 407
395 void ProcessManager::IncrementLazyKeepaliveCountForView( 408 void ProcessManager::IncrementLazyKeepaliveCountForView(
396 RenderViewHost* render_view_host) { 409 RenderViewHost* render_view_host) {
397 WebContents* web_contents = 410 WebContents* web_contents =
398 WebContents::FromRenderViewHost(render_view_host); 411 WebContents::FromRenderViewHost(render_view_host);
399 ViewType view_type = GetViewType(web_contents); 412 ViewType view_type = GetViewType(web_contents);
400 if (view_type != VIEW_TYPE_INVALID && 413 if (view_type != VIEW_TYPE_INVALID &&
401 view_type != VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { 414 view_type != VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) {
402 const Extension* extension = GetExtensionForRenderViewHost( 415 const Extension* extension = GetExtensionForRenderViewHost(
403 render_view_host); 416 render_view_host);
404 if (extension) 417 if (extension)
405 IncrementLazyKeepaliveCount(extension); 418 IncrementLazyKeepaliveCount(extension);
406 } 419 }
407 } 420 }
408 421
422 // This implementation layers on top of the keepalive count. An impulse sets
423 // a per extension flag. On a regular interval that flag is checked. Changes
424 // from the flag not being set to set cause an IncrementLazyKeepaliveCount.
425 void ProcessManager::KeepaliveImpulse(const Extension* extension) {
426 if (!BackgroundInfo::HasLazyBackgroundPage(extension))
427 return;
428
429 BackgroundPageData& bd = background_page_data_[extension->id()];
430
431 if (!bd.keepalive_impulse) {
432 bd.keepalive_impulse = true;
433 if (!bd.previous_keepalive_impulse) {
434 IncrementLazyKeepaliveCount(extension);
435 }
436 }
437 }
438
439 // DecrementLazyKeepaliveCount is called when no calls to KeepaliveImpulse
440 // have been made for at least event_page_idle_time_. In the best case an
441 // impulse was made just before being cleared, and the decrement will occur
442 // event_page_idle_time_ later, causing a 2 * event_page_idle_time_ total time
443 // for extension to be shut down based on impulses. Worst case is an impulse
444 // just after a clear, adding one check cycle and resulting in 3x total time.
445 void ProcessManager::OnKeepaliveImpulseCheck() {
446 for (BackgroundPageDataMap::iterator i = background_page_data_.begin();
447 i != background_page_data_.end();
448 ++i) {
449 bool this_impulse = i->second.keepalive_impulse;
450 bool previous_impulse = i->second.previous_keepalive_impulse;
451 i->second.keepalive_impulse = false;
452 i->second.previous_keepalive_impulse = this_impulse;
453
454 if (previous_impulse && !this_impulse) {
455 DecrementLazyKeepaliveCountById(i->first);
456 }
457 }
458
459 base::MessageLoop::current()->PostDelayedTask(
460 FROM_HERE,
Matt Perry 2013/11/19 21:35:08 nit: indent to 4
scheib 2013/11/19 23:18:25 Done.
461 base::Bind(&ProcessManager::OnKeepaliveImpulseCheck,
462 weak_ptr_factory_.GetWeakPtr()),
463 event_page_idle_time_);
464 }
465
409 void ProcessManager::OnLazyBackgroundPageIdle(const std::string& extension_id, 466 void ProcessManager::OnLazyBackgroundPageIdle(const std::string& extension_id,
410 int sequence_id) { 467 int sequence_id) {
411 ExtensionHost* host = GetBackgroundHostForExtension(extension_id); 468 ExtensionHost* host = GetBackgroundHostForExtension(extension_id);
412 if (host && !background_page_data_[extension_id].is_closing && 469 if (host && !background_page_data_[extension_id].is_closing &&
413 sequence_id == background_page_data_[extension_id].close_sequence_id) { 470 sequence_id == background_page_data_[extension_id].close_sequence_id) {
414 // Tell the renderer we are about to close. This is a simple ping that the 471 // Tell the renderer we are about to close. This is a simple ping that the
415 // renderer will respond to. The purpose is to control sequencing: if the 472 // renderer will respond to. The purpose is to control sequencing: if the
416 // extension remains idle until the renderer responds with an ACK, then we 473 // extension remains idle until the renderer responds with an ACK, then we
417 // know that the extension process is ready to shut down. If our 474 // know that the extension process is ready to shut down. If our
418 // close_sequence_id has already changed, then we would ignore the 475 // close_sequence_id has already changed, then we would ignore the
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after
818 } 875 }
819 876
820 bool IncognitoProcessManager::IsIncognitoEnabled(const Extension* extension) { 877 bool IncognitoProcessManager::IsIncognitoEnabled(const Extension* extension) {
821 // Keep in sync with duplicate in extension_info_map.cc. 878 // Keep in sync with duplicate in extension_info_map.cc.
822 ExtensionService* service = ExtensionSystem::GetForBrowserContext( 879 ExtensionService* service = ExtensionSystem::GetForBrowserContext(
823 GetBrowserContext())->extension_service(); 880 GetBrowserContext())->extension_service();
824 return extension_util::IsIncognitoEnabled(extension->id(), service); 881 return extension_util::IsIncognitoEnabled(extension->id(), service);
825 } 882 }
826 883
827 } // namespace extensions 884 } // namespace extensions
OLDNEW
« no previous file with comments | « extensions/browser/process_manager.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698