Chromium Code Reviews| 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); |