diff options
author | mpcomplete@chromium.org <mpcomplete@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-28 23:36:23 +0000 |
---|---|---|
committer | mpcomplete@chromium.org <mpcomplete@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-28 23:36:23 +0000 |
commit | 971c16885e6dca38e4f3d5d5ba5b73214e3526e7 (patch) | |
tree | df8db75694b66ac673f8b98dfedf1ef509c1994a /chrome/browser/extensions/extension_host.cc | |
parent | e9e3ffdd0c69ecb48c656bd9bd61a10beb731091 (diff) | |
download | chromium_src-971c16885e6dca38e4f3d5d5ba5b73214e3526e7.zip chromium_src-971c16885e6dca38e4f3d5d5ba5b73214e3526e7.tar.gz chromium_src-971c16885e6dca38e4f3d5d5ba5b73214e3526e7.tar.bz2 |
Retry r27137. Create renderers for ExtensionHosts one at a time to avoid blocking the UI.
I added a process.Close() to the fast shutdown path for renderers. The problem
was that we were trying to use an old terminated process handle.
BUG=14040
TEST=Install a bunch of extensions with toolstrips, then restart Chrome. The
UI should be responsive while the toolstrips are loading.
Review URL: http://codereview.chromium.org/243007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@27434 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/extensions/extension_host.cc')
-rw-r--r-- | chrome/browser/extensions/extension_host.cc | 71 |
1 files changed, 70 insertions, 1 deletions
diff --git a/chrome/browser/extensions/extension_host.cc b/chrome/browser/extensions/extension_host.cc index 8ff822f..84852e2 100644 --- a/chrome/browser/extensions/extension_host.cc +++ b/chrome/browser/extensions/extension_host.cc @@ -4,7 +4,11 @@ #include "chrome/browser/extensions/extension_host.h" +#include <list> + #include "app/resource_bundle.h" +#include "base/message_loop.h" +#include "base/singleton.h" #include "base/string_util.h" #include "chrome/browser/browser.h" #include "chrome/browser/browser_list.h" @@ -40,6 +44,66 @@ bool ExtensionHost::enable_dom_automation_ = false; static const char* kToolstripTextColorSubstitution = "$TEXT_COLOR$"; +// Helper class that rate-limits the creation of renderer processes for +// ExtensionHosts, to avoid blocking the UI. +class ExtensionHost::ProcessCreationQueue { + public: + static ProcessCreationQueue* get() { + return Singleton<ProcessCreationQueue>::get(); + } + + // Add a host to the queue for RenderView creation. + void CreateSoon(ExtensionHost* host) { + queue_.push_back(host); + PostTask(); + } + + // Remove a host from the queue (in case it's being deleted). + void Remove(ExtensionHost* host) { + Queue::iterator it = std::find(queue_.begin(), queue_.end(), host); + if (it != queue_.end()) + queue_.erase(it); + } + + private: + friend class Singleton<ProcessCreationQueue>; + friend struct DefaultSingletonTraits<ProcessCreationQueue>; + ProcessCreationQueue() + : pending_create_(false), + ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) { } + + // Queue up a delayed task to process the next ExtensionHost in the queue. + void PostTask() { + if (!pending_create_) { + MessageLoop::current()->PostTask(FROM_HERE, + method_factory_.NewRunnableMethod( + &ProcessCreationQueue::ProcessOneHost)); + pending_create_ = true; + } + } + + // Create the RenderView for the next host in the queue. + void ProcessOneHost() { + pending_create_ = false; + if (queue_.empty()) + return; // can happen on shutdown + + queue_.front()->CreateRenderViewNow(); + queue_.pop_front(); + + if (!queue_.empty()) + PostTask(); + } + + typedef std::list<ExtensionHost*> Queue; + Queue queue_; + bool pending_create_; + ScopedRunnableMethodFactory<ProcessCreationQueue> method_factory_; +}; + +//////////////// +// ExtensionHost + ExtensionHost::ExtensionHost(Extension* extension, SiteInstance* site_instance, const GURL& url, ViewType::Type host_type) : extension_(extension), @@ -59,6 +123,7 @@ ExtensionHost::~ExtensionHost() { NotificationType::EXTENSION_HOST_DESTROYED, Source<Profile>(profile_), Details<ExtensionHost>(this)); + ProcessCreationQueue::get()->Remove(this); render_view_host_->Shutdown(); // deletes render_view_host } @@ -92,9 +157,13 @@ bool ExtensionHost::IsRenderViewLive() const { return render_view_host_->IsRenderViewLive(); } -void ExtensionHost::CreateRenderView(RenderWidgetHostView* host_view) { +void ExtensionHost::CreateRenderViewSoon(RenderWidgetHostView* host_view) { LOG(INFO) << "Creating RenderView for " + extension_->name(); render_view_host_->set_view(host_view); + ProcessCreationQueue::get()->CreateSoon(this); +} + +void ExtensionHost::CreateRenderViewNow() { render_view_host_->CreateRenderView(); NavigateToURL(url_); DCHECK(IsRenderViewLive()); |