From ae5497ff6e21823ba303e34ed4506bc43af29eba Mon Sep 17 00:00:00 2001 From: "mpcomplete@chromium.org" Date: Thu, 5 Nov 2009 00:39:46 +0000 Subject: Fix a bug where we'd leak ResourceMessageFilters and BrowserRenderProcessHosts on shutdown when extensions were running. BUG=15708 BUG=26652 Review URL: http://codereview.chromium.org/355032 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@31045 0039d316-1c4b-4281-b951-d872f2087c98 --- .../extensions/extension_process_manager.cc | 27 +++++++++++++++++----- .../browser/extensions/extension_process_manager.h | 3 +++ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/chrome/browser/extensions/extension_process_manager.cc b/chrome/browser/extensions/extension_process_manager.cc index 6718691..06f3d58 100644 --- a/chrome/browser/extensions/extension_process_manager.cc +++ b/chrome/browser/extensions/extension_process_manager.cc @@ -44,15 +44,12 @@ ExtensionProcessManager::ExtensionProcessManager(Profile* profile) NotificationService::AllSources()); registrar_.Add(this, NotificationType::RENDERER_PROCESS_CLOSED, NotificationService::AllSources()); + registrar_.Add(this, NotificationType::BROWSER_CLOSED, + NotificationService::AllSources()); } ExtensionProcessManager::~ExtensionProcessManager() { - // Copy all_hosts_ to avoid iterator invalidation issues. - ExtensionHostSet to_delete(background_hosts_.begin(), - background_hosts_.end()); - ExtensionHostSet::iterator iter; - for (iter = to_delete.begin(); iter != to_delete.end(); ++iter) - delete *iter; + DCHECK(background_hosts_.empty()); } ExtensionHost* ExtensionProcessManager::CreateView(Extension* extension, @@ -217,6 +214,16 @@ void ExtensionProcessManager::Observe(NotificationType type, break; } + case NotificationType::BROWSER_CLOSED: { + // Close background hosts when the last browser is closed so that they + // have time to shutdown various objects on different threads. Our + // destructor is called too late in the shutdown sequence. + bool app_closing = *Details(details).ptr(); + if (app_closing) + CloseBackgroundHosts(); + break; + } + default: NOTREACHED(); } @@ -232,3 +239,11 @@ void ExtensionProcessManager::OnExtensionHostCreated(ExtensionHost* host, Source(this), Details(host)); } + +void ExtensionProcessManager::CloseBackgroundHosts() { + for (ExtensionHostSet::iterator iter = background_hosts_.begin(); + iter != background_hosts_.end(); ) { + ExtensionHostSet::iterator current = iter++; + delete *current; + } +} diff --git a/chrome/browser/extensions/extension_process_manager.h b/chrome/browser/extensions/extension_process_manager.h index e154a33..d2d62ef 100644 --- a/chrome/browser/extensions/extension_process_manager.h +++ b/chrome/browser/extensions/extension_process_manager.h @@ -83,6 +83,9 @@ class ExtensionProcessManager : public NotificationObserver { // Called just after |host| is created so it can be registered in our lists. void OnExtensionHostCreated(ExtensionHost* host, bool is_background); + // Called on browser shutdown to close our extension hosts. + void CloseBackgroundHosts(); + NotificationRegistrar registrar_; // The set of all ExtensionHosts managed by this process manager. -- cgit v1.1