Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(185)

Side by Side Diff: chrome/browser/extensions/extension_host.cc

Issue 220028: Create renderers for ExtensionHosts one a time to avoid blocking the UI. (Closed)
Patch Set: scoped task factory Created 11 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/extensions/extension_host.h" 5 #include "chrome/browser/extensions/extension_host.h"
6 6
7 #include <list>
8
7 #include "app/resource_bundle.h" 9 #include "app/resource_bundle.h"
10 #include "base/message_loop.h"
11 #include "base/singleton.h"
8 #include "base/string_util.h" 12 #include "base/string_util.h"
9 #include "chrome/browser/browser.h" 13 #include "chrome/browser/browser.h"
10 #include "chrome/browser/browser_list.h" 14 #include "chrome/browser/browser_list.h"
11 #include "chrome/browser/browser_theme_provider.h" 15 #include "chrome/browser/browser_theme_provider.h"
12 #include "chrome/browser/debugger/devtools_manager.h" 16 #include "chrome/browser/debugger/devtools_manager.h"
13 #include "chrome/browser/extensions/extension_message_service.h" 17 #include "chrome/browser/extensions/extension_message_service.h"
14 #include "chrome/browser/extensions/extension_tabs_module.h" 18 #include "chrome/browser/extensions/extension_tabs_module.h"
15 #include "chrome/browser/profile.h" 19 #include "chrome/browser/profile.h"
16 #include "chrome/browser/renderer_host/render_view_host.h" 20 #include "chrome/browser/renderer_host/render_view_host.h"
17 #include "chrome/browser/renderer_host/render_process_host.h" 21 #include "chrome/browser/renderer_host/render_process_host.h"
(...skipping 14 matching lines...) Expand all
32 #include "webkit/glue/context_menu.h" 36 #include "webkit/glue/context_menu.h"
33 37
34 using WebKit::WebDragOperation; 38 using WebKit::WebDragOperation;
35 using WebKit::WebDragOperationsMask; 39 using WebKit::WebDragOperationsMask;
36 40
37 // static 41 // static
38 bool ExtensionHost::enable_dom_automation_ = false; 42 bool ExtensionHost::enable_dom_automation_ = false;
39 43
40 static const char* kToolstripTextColorSubstitution = "$TEXT_COLOR$"; 44 static const char* kToolstripTextColorSubstitution = "$TEXT_COLOR$";
41 45
46 // Helper class that rate-limits the creation of renderer processes for
47 // ExtensionHosts, to avoid blocking the UI.
48 class ExtensionHost::ProcessCreationQueue {
49 public:
50 static ProcessCreationQueue* get() {
51 return Singleton<ProcessCreationQueue>::get();
52 }
53
54 // Add a host to the queue for RenderView creation.
55 void CreateSoon(ExtensionHost* host) {
56 queue_.push_back(host);
57 PostTask();
58 }
59
60 // Remove a host from the queue (in case it's being deleted).
61 void Remove(ExtensionHost* host) {
62 Queue::iterator it = std::find(queue_.begin(), queue_.end(), host);
63 if (it != queue_.end())
64 queue_.erase(it);
65 }
66
67 private:
68 friend class Singleton<ProcessCreationQueue>;
69 friend struct DefaultSingletonTraits<ProcessCreationQueue>;
70 ProcessCreationQueue()
71 : pending_create_(false),
72 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) { }
73
74 // Queue up a delayed task to process the next ExtensionHost in the queue.
75 void PostTask() {
76 if (!pending_create_) {
77 MessageLoop::current()->PostTask(FROM_HERE,
78 method_factory_.NewRunnableMethod(
79 &ProcessCreationQueue::ProcessOneHost));
80 pending_create_ = true;
81 }
82 }
83
84 // Create the RenderView for the next host in the queue.
85 void ProcessOneHost() {
86 pending_create_ = false;
87 if (queue_.empty())
88 return; // can happen on shutdown
89
90 queue_.front()->CreateRenderViewNow();
91 queue_.pop_front();
92
93 if (!queue_.empty())
94 PostTask();
95 }
96
97 typedef std::list<ExtensionHost*> Queue;
98 Queue queue_;
99 bool pending_create_;
100 ScopedRunnableMethodFactory<ProcessCreationQueue> method_factory_;
101 };
102
103 ////////////////
104 // ExtensionHost
105
42 ExtensionHost::ExtensionHost(Extension* extension, SiteInstance* site_instance, 106 ExtensionHost::ExtensionHost(Extension* extension, SiteInstance* site_instance,
43 const GURL& url, ViewType::Type host_type) 107 const GURL& url, ViewType::Type host_type)
44 : extension_(extension), 108 : extension_(extension),
45 profile_(site_instance->browsing_instance()->profile()), 109 profile_(site_instance->browsing_instance()->profile()),
46 did_stop_loading_(false), 110 did_stop_loading_(false),
47 document_element_available_(false), 111 document_element_available_(false),
48 url_(url), 112 url_(url),
49 extension_host_type_(host_type) { 113 extension_host_type_(host_type) {
50 render_view_host_ = new RenderViewHost( 114 render_view_host_ = new RenderViewHost(
51 site_instance, this, MSG_ROUTING_NONE, NULL); 115 site_instance, this, MSG_ROUTING_NONE, NULL);
52 render_view_host_->AllowBindings(BindingsPolicy::EXTENSION); 116 render_view_host_->AllowBindings(BindingsPolicy::EXTENSION);
53 if (enable_dom_automation_) 117 if (enable_dom_automation_)
54 render_view_host_->AllowBindings(BindingsPolicy::DOM_AUTOMATION); 118 render_view_host_->AllowBindings(BindingsPolicy::DOM_AUTOMATION);
55 } 119 }
56 120
57 ExtensionHost::~ExtensionHost() { 121 ExtensionHost::~ExtensionHost() {
58 NotificationService::current()->Notify( 122 NotificationService::current()->Notify(
59 NotificationType::EXTENSION_HOST_DESTROYED, 123 NotificationType::EXTENSION_HOST_DESTROYED,
60 Source<Profile>(profile_), 124 Source<Profile>(profile_),
61 Details<ExtensionHost>(this)); 125 Details<ExtensionHost>(this));
126 ProcessCreationQueue::get()->Remove(this);
62 render_view_host_->Shutdown(); // deletes render_view_host 127 render_view_host_->Shutdown(); // deletes render_view_host
63 } 128 }
64 129
65 void ExtensionHost::CreateView(Browser* browser) { 130 void ExtensionHost::CreateView(Browser* browser) {
66 #if defined(TOOLKIT_VIEWS) 131 #if defined(TOOLKIT_VIEWS)
67 view_.reset(new ExtensionView(this, browser)); 132 view_.reset(new ExtensionView(this, browser));
68 // We own |view_|, so don't auto delete when it's removed from the view 133 // We own |view_|, so don't auto delete when it's removed from the view
69 // hierarchy. 134 // hierarchy.
70 view_->SetParentOwned(false); 135 view_->SetParentOwned(false);
71 #elif defined(OS_LINUX) 136 #elif defined(OS_LINUX)
(...skipping 13 matching lines...) Expand all
85 } 150 }
86 151
87 SiteInstance* ExtensionHost::site_instance() const { 152 SiteInstance* ExtensionHost::site_instance() const {
88 return render_view_host_->site_instance(); 153 return render_view_host_->site_instance();
89 } 154 }
90 155
91 bool ExtensionHost::IsRenderViewLive() const { 156 bool ExtensionHost::IsRenderViewLive() const {
92 return render_view_host_->IsRenderViewLive(); 157 return render_view_host_->IsRenderViewLive();
93 } 158 }
94 159
95 void ExtensionHost::CreateRenderView(RenderWidgetHostView* host_view) { 160 void ExtensionHost::CreateRenderViewSoon(RenderWidgetHostView* host_view) {
96 render_view_host_->set_view(host_view); 161 render_view_host_->set_view(host_view);
162 ProcessCreationQueue::get()->CreateSoon(this);
163 }
164
165 void ExtensionHost::CreateRenderViewNow() {
97 render_view_host_->CreateRenderView(); 166 render_view_host_->CreateRenderView();
98 NavigateToURL(url_); 167 NavigateToURL(url_);
99 DCHECK(IsRenderViewLive()); 168 DCHECK(IsRenderViewLive());
100 NotificationService::current()->Notify( 169 NotificationService::current()->Notify(
101 NotificationType::EXTENSION_PROCESS_CREATED, 170 NotificationType::EXTENSION_PROCESS_CREATED,
102 Source<Profile>(profile_), 171 Source<Profile>(profile_),
103 Details<ExtensionHost>(this)); 172 Details<ExtensionHost>(this));
104 } 173 }
105 174
106 void ExtensionHost::NavigateToURL(const GURL& url) { 175 void ExtensionHost::NavigateToURL(const GURL& url) {
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
397 window_id = ExtensionTabUtil::GetWindowId( 466 window_id = ExtensionTabUtil::GetWindowId(
398 const_cast<ExtensionHost* >(this)->GetBrowser()); 467 const_cast<ExtensionHost* >(this)->GetBrowser());
399 } else if (extension_host_type_ == ViewType::EXTENSION_BACKGROUND_PAGE) { 468 } else if (extension_host_type_ == ViewType::EXTENSION_BACKGROUND_PAGE) {
400 // Background page is not attached to any browser window, so pass -1. 469 // Background page is not attached to any browser window, so pass -1.
401 window_id = -1; 470 window_id = -1;
402 } else { 471 } else {
403 NOTREACHED(); 472 NOTREACHED();
404 } 473 }
405 return window_id; 474 return window_id;
406 } 475 }
OLDNEW
« no previous file with comments | « chrome/browser/extensions/extension_host.h ('k') | chrome/browser/extensions/extension_process_manager.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698