Index: extensions/browser/process_manager.cc |
diff --git a/extensions/browser/process_manager.cc b/extensions/browser/process_manager.cc |
index cccb800ac2153287920116a0ed0a631aec1af36e..f718a476530e9166f7d303158c6486a75f8c1483 100644 |
--- a/extensions/browser/process_manager.cc |
+++ b/extensions/browser/process_manager.cc |
@@ -137,6 +137,10 @@ struct ProcessManager::BackgroundPageData { |
// The count of things keeping the lazy background page alive. |
int lazy_keepalive_count; |
+ // Tracks if an impulse event has occured since the last polling check. |
+ bool keepalive_impulse; |
+ bool previous_keepalive_impulse; |
+ |
// This is used with the ShouldSuspend message, to ensure that the extension |
// remained idle between sending the message and receiving the ack. |
int close_sequence_id; |
@@ -151,7 +155,11 @@ struct ProcessManager::BackgroundPageData { |
linked_ptr<base::ElapsedTimer> since_suspended; |
BackgroundPageData() |
- : lazy_keepalive_count(0), close_sequence_id(0), is_closing(false) {} |
+ : lazy_keepalive_count(0), |
+ keepalive_impulse(false), |
+ previous_keepalive_impulse(false), |
+ close_sequence_id(0), |
+ is_closing(false) {} |
}; |
// |
@@ -217,6 +225,8 @@ ProcessManager::ProcessManager(BrowserContext* context, |
content::DevToolsManager::GetInstance()->AddAgentStateCallback( |
devtools_callback_); |
+ |
+ OnKeepaliveImpulseCheck(); |
} |
ProcessManager::~ProcessManager() { |
@@ -372,20 +382,23 @@ int ProcessManager::IncrementLazyKeepaliveCount(const Extension* extension) { |
int ProcessManager::DecrementLazyKeepaliveCount(const Extension* extension) { |
if (!BackgroundInfo::HasLazyBackgroundPage(extension)) |
return 0; |
+ return DecrementLazyKeepaliveCountById(extension->id()); |
+} |
- int& count = background_page_data_[extension->id()].lazy_keepalive_count; |
+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.
|
+ int& count = background_page_data_[extension_id].lazy_keepalive_count; |
DCHECK_GT(count, 0); |
// If we reach a zero keepalive count when the lazy background page is about |
// to be closed, incrementing close_sequence_id will cancel the close |
// sequence and cause the background page to linger. So check is_closing |
// before initiating another close sequence. |
- if (--count == 0 && !background_page_data_[extension->id()].is_closing) { |
+ if (--count == 0 && !background_page_data_[extension_id].is_closing) { |
base::MessageLoop::current()->PostDelayedTask( |
FROM_HERE, |
base::Bind(&ProcessManager::OnLazyBackgroundPageIdle, |
- weak_ptr_factory_.GetWeakPtr(), extension->id(), |
- ++background_page_data_[extension->id()].close_sequence_id), |
+ weak_ptr_factory_.GetWeakPtr(), extension_id, |
+ ++background_page_data_[extension_id].close_sequence_id), |
event_page_idle_time_); |
} |
@@ -406,6 +419,50 @@ void ProcessManager::IncrementLazyKeepaliveCountForView( |
} |
} |
+// This implementation layers on top of the keepalive count. An impulse sets |
+// a per extension flag. On a regular interval that flag is checked. Changes |
+// from the flag not being set to set cause an IncrementLazyKeepaliveCount. |
+void ProcessManager::KeepaliveImpulse(const Extension* extension) { |
+ if (!BackgroundInfo::HasLazyBackgroundPage(extension)) |
+ return; |
+ |
+ BackgroundPageData& bd = background_page_data_[extension->id()]; |
+ |
+ if (!bd.keepalive_impulse) { |
+ bd.keepalive_impulse = true; |
+ if (!bd.previous_keepalive_impulse) { |
+ IncrementLazyKeepaliveCount(extension); |
+ } |
+ } |
+} |
+ |
+// DecrementLazyKeepaliveCount is called when no calls to KeepaliveImpulse |
+// have been made for at least event_page_idle_time_. In the best case an |
+// impulse was made just before being cleared, and the decrement will occur |
+// event_page_idle_time_ later, causing a 2 * event_page_idle_time_ total time |
+// for extension to be shut down based on impulses. Worst case is an impulse |
+// just after a clear, adding one check cycle and resulting in 3x total time. |
+void ProcessManager::OnKeepaliveImpulseCheck() { |
+ for (BackgroundPageDataMap::iterator i = background_page_data_.begin(); |
+ i != background_page_data_.end(); |
+ ++i) { |
+ bool this_impulse = i->second.keepalive_impulse; |
+ bool previous_impulse = i->second.previous_keepalive_impulse; |
+ i->second.keepalive_impulse = false; |
+ i->second.previous_keepalive_impulse = this_impulse; |
+ |
+ if (previous_impulse && !this_impulse) { |
+ DecrementLazyKeepaliveCountById(i->first); |
+ } |
+ } |
+ |
+ base::MessageLoop::current()->PostDelayedTask( |
+ FROM_HERE, |
Matt Perry
2013/11/19 21:35:08
nit: indent to 4
scheib
2013/11/19 23:18:25
Done.
|
+ base::Bind(&ProcessManager::OnKeepaliveImpulseCheck, |
+ weak_ptr_factory_.GetWeakPtr()), |
+ event_page_idle_time_); |
+} |
+ |
void ProcessManager::OnLazyBackgroundPageIdle(const std::string& extension_id, |
int sequence_id) { |
ExtensionHost* host = GetBackgroundHostForExtension(extension_id); |