Chromium Code Reviews| Index: extensions/browser/process_manager.cc |
| diff --git a/extensions/browser/process_manager.cc b/extensions/browser/process_manager.cc |
| index a1ee794ace65ef55a82aa923bf09acabab0e1e1a..844257df7d2e0a3c3309744c9ab5d07aa24b863c 100644 |
| --- a/extensions/browser/process_manager.cc |
| +++ b/extensions/browser/process_manager.cc |
| @@ -133,6 +133,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; |
| @@ -147,7 +151,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) {} |
| }; |
| // |
| @@ -197,22 +205,25 @@ ProcessManager::ProcessManager(BrowserContext* context, |
| } |
| event_page_idle_time_ = base::TimeDelta::FromSeconds(10); |
| - unsigned idle_time_sec = 0; |
| + unsigned idle_time_msec = 0; |
| if (base::StringToUint(CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
| - extensions::switches::kEventPageIdleTime), &idle_time_sec)) { |
| - event_page_idle_time_ = base::TimeDelta::FromSeconds(idle_time_sec); |
| + extensions::switches::kEventPageIdleTime), &idle_time_msec)) { |
| + CHECK(idle_time_msec > 0); // OnKeepaliveImpulseCheck requires non zero. |
|
tapted
2013/11/28 03:03:37
optional nit: maybe CHECK_NE(0u, idle_time_msec)?
scheib
2013/12/02 21:22:38
I think this check output is pretty clear as is wi
|
| + event_page_idle_time_ = base::TimeDelta::FromMilliseconds(idle_time_msec); |
| } |
| event_page_suspending_time_ = base::TimeDelta::FromSeconds(5); |
| - unsigned suspending_time_sec = 0; |
| + unsigned suspending_time_msec = 0; |
| if (base::StringToUint(CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
| extensions::switches::kEventPageSuspendingTime), |
| - &suspending_time_sec)) { |
| + &suspending_time_msec)) { |
| event_page_suspending_time_ = |
| - base::TimeDelta::FromSeconds(suspending_time_sec); |
| + base::TimeDelta::FromMilliseconds(suspending_time_msec); |
| } |
| content::DevToolsManager::GetInstance()->AddAgentStateCallback( |
| devtools_callback_); |
| + |
| + OnKeepaliveImpulseCheck(); |
| } |
| ProcessManager::~ProcessManager() { |
| @@ -360,20 +371,23 @@ int ProcessManager::IncrementLazyKeepaliveCount(const Extension* extension) { |
| int ProcessManager::DecrementLazyKeepaliveCount(const Extension* extension) { |
| if (!BackgroundInfo::HasLazyBackgroundPage(extension)) |
| return 0; |
| + return DecrementLazyKeepaliveCount(extension->id()); |
| +} |
| - int& count = background_page_data_[extension->id()].lazy_keepalive_count; |
| +int ProcessManager::DecrementLazyKeepaliveCount(std::string extension_id) { |
| + 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_); |
| } |
| @@ -394,6 +408,51 @@ 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; |
|
tapted
2013/11/28 03:03:37
(optional) This might be easier to read without th
scheib
2013/12/02 21:22:38
Done; your first suggestion. The latter didn't reu
|
| + 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) |
| + DecrementLazyKeepaliveCount(i->first); |
|
tapted
2013/11/28 03:03:37
I thought it weird that the return value wasn't ch
scheib
2013/12/02 21:22:38
Done.
|
| + } |
| + |
| + if (base::MessageLoop::current()) { |
|
tapted
2013/11/28 03:03:37
Maybe a comment here to explain this check (e.g. S
scheib
2013/12/02 21:22:38
Done.
|
| + base::MessageLoop::current()->PostDelayedTask( |
| + FROM_HERE, |
| + 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); |