Index: chrome/browser/extensions/extension_process_manager.cc |
diff --git a/chrome/browser/extensions/extension_process_manager.cc b/chrome/browser/extensions/extension_process_manager.cc |
index 47ec735fa0fbc35f8d94e5b215075fd02b9d84c9..cf7230f675a9beef6f439f1a6f62540e7ccab633 100644 |
--- a/chrome/browser/extensions/extension_process_manager.cc |
+++ b/chrome/browser/extensions/extension_process_manager.cc |
@@ -5,6 +5,9 @@ |
#include "base/bind.h" |
#include "base/command_line.h" |
#include "base/lazy_instance.h" |
+#include "base/message_loop.h" |
+#include "base/string_number_conversions.h" |
+#include "base/time.h" |
#include "chrome/browser/extensions/extension_event_router.h" |
#include "chrome/browser/extensions/extension_process_manager.h" |
#include "chrome/browser/extensions/extension_host.h" |
@@ -125,7 +128,8 @@ ExtensionProcessManager* ExtensionProcessManager::Create(Profile* profile) { |
} |
ExtensionProcessManager::ExtensionProcessManager(Profile* profile) |
- : site_instance_(SiteInstance::Create(profile)) { |
+ : site_instance_(SiteInstance::Create(profile)), |
+ weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
Profile* original_profile = profile->GetOriginalProfile(); |
registrar_.Add(this, chrome::NOTIFICATION_EXTENSIONS_READY, |
content::Source<Profile>(original_profile)); |
@@ -145,6 +149,20 @@ ExtensionProcessManager::ExtensionProcessManager(Profile* profile) |
content::Source<content::BrowserContext>(profile)); |
registrar_.Add(this, content::NOTIFICATION_DEVTOOLS_WINDOW_CLOSING, |
content::Source<content::BrowserContext>(profile)); |
+ |
+ event_page_idle_time_ = base::TimeDelta::FromSeconds(10); |
+ unsigned idle_time_sec = 0; |
+ if (base::StringToUint(CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
+ switches::kEventPageIdleTime), &idle_time_sec)) { |
+ event_page_idle_time_ = base::TimeDelta::FromSeconds(idle_time_sec); |
+ } |
+ event_page_unloading_time_ = base::TimeDelta::FromSeconds(5); |
+ unsigned unloading_time_sec = 0; |
+ if (base::StringToUint(CommandLine::ForCurrentProcess()->GetSwitchValueASCII( |
+ switches::kEventPageUnloadingTime), &unloading_time_sec)) { |
+ event_page_unloading_time_ = base::TimeDelta::FromSeconds( |
+ unloading_time_sec); |
+ } |
} |
ExtensionProcessManager::~ExtensionProcessManager() { |
@@ -414,22 +432,31 @@ int ExtensionProcessManager::DecrementLazyKeepaliveCount( |
int& count = background_page_data_[extension->id()].lazy_keepalive_count; |
DCHECK_GT(count, 0); |
- if (--count == 0) |
- OnLazyBackgroundPageIdle(extension->id()); |
+ if (--count == 0) { |
+ MessageLoop::current()->PostDelayedTask( |
+ FROM_HERE, |
+ base::Bind(&ExtensionProcessManager::OnLazyBackgroundPageIdle, |
+ weak_ptr_factory_.GetWeakPtr(), extension->id(), |
+ ++background_page_data_[extension->id()].close_sequence_id), |
+ event_page_idle_time_); |
+ } |
return count; |
} |
void ExtensionProcessManager::OnLazyBackgroundPageIdle( |
- const std::string& extension_id) { |
+ const std::string& extension_id, int sequence_id) { |
ExtensionHost* host = GetBackgroundHostForExtension(extension_id); |
- if (host && !background_page_data_[extension_id].is_closing) { |
+ if (host && !background_page_data_[extension_id].is_closing && |
+ sequence_id == background_page_data_[extension_id].close_sequence_id) { |
// Tell the renderer we are about to close. This is a simple ping that the |
// renderer will respond to. The purpose is to control sequencing: if the |
// extension remains idle until the renderer responds with an ACK, then we |
- // know that the extension process is ready to shut down. |
+ // know that the extension process is ready to shut down. If our |
+ // close_sequence_id has already changed, then we would ignore the |
+ // ShouldUnloadAck, so we don't send the ping. |
host->render_view_host()->Send(new ExtensionMsg_ShouldUnload( |
- extension_id, ++background_page_data_[extension_id].close_sequence_id)); |
+ extension_id, sequence_id)); |
} |
} |
@@ -449,10 +476,21 @@ void ExtensionProcessManager::OnShouldUnloadAck( |
if (host && |
sequence_id == background_page_data_[extension_id].close_sequence_id) { |
background_page_data_[extension_id].is_closing = true; |
- host->render_view_host()->Send(new ExtensionMsg_Unload(extension_id)); |
+ MessageLoop::current()->PostDelayedTask( |
+ FROM_HERE, |
+ base::Bind(&ExtensionProcessManager::CloseLazyBackgroundPageNow, |
+ weak_ptr_factory_.GetWeakPtr(), extension_id), |
+ event_page_unloading_time_); |
} |
} |
+void ExtensionProcessManager::CloseLazyBackgroundPageNow( |
+ const std::string& extension_id) { |
+ ExtensionHost* host = GetBackgroundHostForExtension(extension_id); |
+ if (host) |
+ host->render_view_host()->Send(new ExtensionMsg_Unload(extension_id)); |
+} |
+ |
void ExtensionProcessManager::OnUnloadAck(const std::string& extension_id) { |
ExtensionHost* host = GetBackgroundHostForExtension(extension_id); |
if (host) |