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

Side by Side Diff: chrome/renderer/render_thread.cc

Issue 155944: Switch the first thread in a child process to be the main thread... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: sync Created 11 years, 5 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 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/renderer/render_thread.h" 5 #include "chrome/renderer/render_thread.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/command_line.h" 10 #include "base/command_line.h"
11 #include "base/lazy_instance.h" 11 #include "base/lazy_instance.h"
12 #include "base/shared_memory.h" 12 #include "base/shared_memory.h"
13 #include "base/stats_table.h" 13 #include "base/stats_table.h"
14 #include "base/thread_local.h" 14 #include "base/thread_local.h"
15 #include "chrome/common/app_cache/app_cache_context_impl.h" 15 #include "chrome/common/app_cache/app_cache_context_impl.h"
16 #include "chrome/common/app_cache/app_cache_dispatcher.h" 16 #include "chrome/common/app_cache/app_cache_dispatcher.h"
17 #include "chrome/common/chrome_switches.h" 17 #include "chrome/common/chrome_switches.h"
18 #include "chrome/common/render_messages.h" 18 #include "chrome/common/render_messages.h"
19 #include "chrome/common/renderer_preferences.h" 19 #include "chrome/common/renderer_preferences.h"
20 #include "chrome/common/notification_service.h"
21 #include "chrome/common/url_constants.h" 20 #include "chrome/common/url_constants.h"
22 #include "chrome/plugin/npobject_util.h" 21 #include "chrome/plugin/npobject_util.h"
23 // TODO(port) 22 // TODO(port)
24 #if defined(OS_WIN) 23 #if defined(OS_WIN)
25 #include "chrome/plugin/plugin_channel.h" 24 #include "chrome/plugin/plugin_channel.h"
26 #else 25 #else
27 #include "base/scoped_handle.h" 26 #include "base/scoped_handle.h"
28 #include "chrome/plugin/plugin_channel_base.h" 27 #include "chrome/plugin/plugin_channel_base.h"
29 #endif 28 #endif
30 #include "chrome/renderer/devtools_agent_filter.h" 29 #include "chrome/renderer/devtools_agent_filter.h"
(...skipping 17 matching lines...) Expand all
48 #include "webkit/extensions/v8/playback_extension.h" 47 #include "webkit/extensions/v8/playback_extension.h"
49 48
50 #if defined(OS_WIN) 49 #if defined(OS_WIN)
51 #include <windows.h> 50 #include <windows.h>
52 #include <objbase.h> 51 #include <objbase.h>
53 #endif 52 #endif
54 53
55 using WebKit::WebCache; 54 using WebKit::WebCache;
56 using WebKit::WebString; 55 using WebKit::WebString;
57 56
57 namespace {
58 static const unsigned int kCacheStatsDelayMS = 2000 /* milliseconds */; 58 static const unsigned int kCacheStatsDelayMS = 2000 /* milliseconds */;
59
60 static base::LazyInstance<base::ThreadLocalPointer<RenderThread> > lazy_tls( 59 static base::LazyInstance<base::ThreadLocalPointer<RenderThread> > lazy_tls(
61 base::LINKER_INITIALIZED); 60 base::LINKER_INITIALIZED);
62
63 //-----------------------------------------------------------------------------
64 // Methods below are only called on the owner's thread:
65
66 // When we run plugins in process, we actually run them on the render thread,
67 // which means that we need to make the render thread pump UI events.
68 RenderThread::RenderThread()
69 : ChildThread(
70 base::Thread::Options(RenderProcess::InProcessPlugins() ?
71 MessageLoop::TYPE_UI : MessageLoop::TYPE_DEFAULT, kV8StackSize)),
72 plugin_refresh_allowed_(true) {
73 }
74
75 RenderThread::RenderThread(const std::string& channel_name)
76 : ChildThread(
77 base::Thread::Options(RenderProcess::InProcessPlugins() ?
78 MessageLoop::TYPE_UI : MessageLoop::TYPE_DEFAULT, kV8StackSize)),
79 plugin_refresh_allowed_(true) {
80 SetChannelName(channel_name);
81 }
82
83 RenderThread::~RenderThread() {
84 }
85
86 RenderThread* RenderThread::current() {
87 return lazy_tls.Pointer()->Get();
88 }
89
90 void RenderThread::AddFilter(IPC::ChannelProxy::MessageFilter* filter) {
91 channel()->AddFilter(filter);
92 }
93
94 void RenderThread::RemoveFilter(IPC::ChannelProxy::MessageFilter* filter) {
95 channel()->RemoveFilter(filter);
96 }
97
98 void RenderThread::Resolve(const char* name, size_t length) {
99 return dns_master_->Resolve(name, length);
100 }
101
102 void RenderThread::SendHistograms(int sequence_number) {
103 return histogram_snapshots_->SendHistograms(sequence_number);
104 }
105
106 static WebAppCacheContext* CreateAppCacheContextForRenderer() { 61 static WebAppCacheContext* CreateAppCacheContextForRenderer() {
107 return new AppCacheContextImpl(RenderThread::current()); 62 return new AppCacheContextImpl(RenderThread::current());
108 } 63 }
109 64
110 #if defined(OS_POSIX) 65 #if defined(OS_POSIX)
111 class SuicideOnChannelErrorFilter : public IPC::ChannelProxy::MessageFilter { 66 class SuicideOnChannelErrorFilter : public IPC::ChannelProxy::MessageFilter {
112 void OnChannelError() { 67 void OnChannelError() {
113 // On POSIX, at least, one can install an unload handler which loops 68 // On POSIX, at least, one can install an unload handler which loops
114 // forever and leave behind a renderer process which eats 100% CPU forever. 69 // forever and leave behind a renderer process which eats 100% CPU forever.
115 // 70 //
116 // This is because the terminate signals (ViewMsg_ShouldClose and the error 71 // This is because the terminate signals (ViewMsg_ShouldClose and the error
117 // from the IPC channel) are routed to the main message loop but never 72 // from the IPC channel) are routed to the main message loop but never
118 // processed (because that message loop is stuck in V8). 73 // processed (because that message loop is stuck in V8).
119 // 74 //
120 // One could make the browser SIGKILL the renderers, but that leaves open a 75 // One could make the browser SIGKILL the renderers, but that leaves open a
121 // large window where a browser failure (or a user, manually terminating 76 // large window where a browser failure (or a user, manually terminating
122 // the browser because "it's stuck") will leave behind a process eating all 77 // the browser because "it's stuck") will leave behind a process eating all
123 // the CPU. 78 // the CPU.
124 // 79 //
125 // So, we install a filter on the channel so that we can process this event 80 // So, we install a filter on the channel so that we can process this event
126 // here and kill the process. 81 // here and kill the process.
127 _exit(0); 82 _exit(0);
128 } 83 }
129 }; 84 };
130 #endif 85 #endif
86 } // namespace
87
88 // When we run plugins in process, we actually run them on the render thread,
89 // which means that we need to make the render thread pump UI events.
90 RenderThread::RenderThread() {
91 Init();
92 }
93
94 RenderThread::RenderThread(const std::string& channel_name)
95 : ChildThread(channel_name) {
96 Init();
97 }
131 98
132 void RenderThread::Init() { 99 void RenderThread::Init() {
133 lazy_tls.Pointer()->Set(this); 100 lazy_tls.Pointer()->Set(this);
134 #if defined(OS_WIN) 101 #if defined(OS_WIN)
135 // If you are running plugins in this thread you need COM active but in 102 // If you are running plugins in this thread you need COM active but in
136 // the normal case you don't. 103 // the normal case you don't.
137 if (RenderProcess::InProcessPlugins()) 104 if (RenderProcess::InProcessPlugins())
138 CoInitialize(0); 105 CoInitialize(0);
139 #endif 106 #endif
140 107
141 ChildThread::Init(); 108 plugin_refresh_allowed_ = true;
142 notification_service_.reset(new NotificationService);
143 cache_stats_factory_.reset( 109 cache_stats_factory_.reset(
144 new ScopedRunnableMethodFactory<RenderThread>(this)); 110 new ScopedRunnableMethodFactory<RenderThread>(this));
145 111
146 visited_link_slave_.reset(new VisitedLinkSlave()); 112 visited_link_slave_.reset(new VisitedLinkSlave());
147 user_script_slave_.reset(new UserScriptSlave()); 113 user_script_slave_.reset(new UserScriptSlave());
148 dns_master_.reset(new RenderDnsMaster()); 114 dns_master_.reset(new RenderDnsMaster());
149 histogram_snapshots_.reset(new RendererHistogramSnapshots()); 115 histogram_snapshots_.reset(new RendererHistogramSnapshots());
150 app_cache_dispatcher_.reset(new AppCacheDispatcher()); 116 app_cache_dispatcher_.reset(new AppCacheDispatcher());
151 WebAppCacheContext::SetFactory(CreateAppCacheContextForRenderer); 117 WebAppCacheContext::SetFactory(CreateAppCacheContextForRenderer);
152 devtools_agent_filter_ = new DevToolsAgentFilter(); 118 devtools_agent_filter_ = new DevToolsAgentFilter();
153 AddFilter(devtools_agent_filter_.get()); 119 AddFilter(devtools_agent_filter_.get());
154 120
155 #if defined(OS_POSIX) 121 #if defined(OS_POSIX)
156 suicide_on_channel_error_filter_ = new SuicideOnChannelErrorFilter; 122 suicide_on_channel_error_filter_ = new SuicideOnChannelErrorFilter;
157 AddFilter(suicide_on_channel_error_filter_.get()); 123 AddFilter(suicide_on_channel_error_filter_.get());
158 #endif 124 #endif
159 } 125 }
160 126
161 void RenderThread::CleanUp() { 127 RenderThread::~RenderThread() {
162 // Shutdown in reverse of the initialization order. 128 // Shutdown in reverse of the initialization order.
163 RemoveFilter(devtools_agent_filter_.get()); 129 RemoveFilter(devtools_agent_filter_.get());
164 devtools_agent_filter_ = NULL;
165 WebAppCacheContext::SetFactory(NULL); 130 WebAppCacheContext::SetFactory(NULL);
166 app_cache_dispatcher_.reset(); 131 if (webkit_client_.get())
167 histogram_snapshots_.reset(); 132 WebKit::shutdown();
168 dns_master_.reset();
169 user_script_slave_.reset();
170 visited_link_slave_.reset();
171 133
172 if (webkit_client_.get()) {
173 WebKit::shutdown();
174 webkit_client_.reset();
175 }
176
177 notification_service_.reset();
178 ChildThread::CleanUp();
179 lazy_tls.Pointer()->Set(NULL); 134 lazy_tls.Pointer()->Set(NULL);
180 135
181 // TODO(port) 136 // TODO(port)
182 #if defined(OS_WIN) 137 #if defined(OS_WIN)
183 // Clean up plugin channels before this thread goes away. 138 // Clean up plugin channels before this thread goes away.
184 PluginChannelBase::CleanupChannels(); 139 PluginChannelBase::CleanupChannels();
185 // Don't call COM if the renderer is in the sandbox. 140 // Don't call COM if the renderer is in the sandbox.
186 if (RenderProcess::InProcessPlugins()) 141 if (RenderProcess::InProcessPlugins())
187 CoUninitialize(); 142 CoUninitialize();
188 #endif 143 #endif
189 } 144 }
190 145
146 RenderThread* RenderThread::current() {
147 return lazy_tls.Pointer()->Get();
148 }
149
150 void RenderThread::AddFilter(IPC::ChannelProxy::MessageFilter* filter) {
151 channel()->AddFilter(filter);
152 }
153
154 void RenderThread::RemoveFilter(IPC::ChannelProxy::MessageFilter* filter) {
155 channel()->RemoveFilter(filter);
156 }
157
158 void RenderThread::Resolve(const char* name, size_t length) {
159 return dns_master_->Resolve(name, length);
160 }
161
162 void RenderThread::SendHistograms(int sequence_number) {
163 return histogram_snapshots_->SendHistograms(sequence_number);
164 }
165
191 void RenderThread::OnUpdateVisitedLinks(base::SharedMemoryHandle table) { 166 void RenderThread::OnUpdateVisitedLinks(base::SharedMemoryHandle table) {
192 DCHECK(base::SharedMemory::IsHandleValid(table)) << "Bad table handle"; 167 DCHECK(base::SharedMemory::IsHandleValid(table)) << "Bad table handle";
193 visited_link_slave_->Init(table); 168 visited_link_slave_->Init(table);
194 } 169 }
195 170
196 void RenderThread::OnAddVisitedLinks( 171 void RenderThread::OnAddVisitedLinks(
197 const VisitedLinkSlave::Fingerprints& fingerprints) { 172 const VisitedLinkSlave::Fingerprints& fingerprints) {
198 for (size_t i = 0; i < fingerprints.size(); ++i) 173 for (size_t i = 0; i < fingerprints.size(); ++i)
199 WebView::UpdateVisitedLinkState(fingerprints[i]); 174 WebView::UpdateVisitedLinkState(fingerprints[i]);
200 } 175 }
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 EnsureWebKitInitialized(); 242 EnsureWebKitInitialized();
268 243
269 // When bringing in render_view, also bring in webkit's glue and jsbindings. 244 // When bringing in render_view, also bring in webkit's glue and jsbindings.
270 base::WaitableEvent* waitable_event = new base::WaitableEvent( 245 base::WaitableEvent* waitable_event = new base::WaitableEvent(
271 #if defined(OS_WIN) 246 #if defined(OS_WIN)
272 modal_dialog_event.event); 247 modal_dialog_event.event);
273 #else 248 #else
274 true, false); 249 true, false);
275 #endif 250 #endif
276 251
277 // TODO(darin): once we have a RenderThread per RenderView, this will need to
278 // change to assert that we are not creating more than one view.
279 RenderView::Create( 252 RenderView::Create(
280 this, parent_hwnd, waitable_event, MSG_ROUTING_NONE, renderer_prefs, 253 this, parent_hwnd, waitable_event, MSG_ROUTING_NONE, renderer_prefs,
281 webkit_prefs, new SharedRenderViewCounter(0), view_id); 254 webkit_prefs, new SharedRenderViewCounter(0), view_id);
282 } 255 }
283 256
284 void RenderThread::OnSetCacheCapacities(size_t min_dead_capacity, 257 void RenderThread::OnSetCacheCapacities(size_t min_dead_capacity,
285 size_t max_dead_capacity, 258 size_t max_dead_capacity,
286 size_t capacity) { 259 size_t capacity) {
287 EnsureWebKitInitialized(); 260 EnsureWebKitInitialized();
288 WebCache::setCapacities( 261 WebCache::setCapacities(
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
405 378
406 void RenderThread::OnPurgePluginListCache() { 379 void RenderThread::OnPurgePluginListCache() {
407 // The call below will cause a GetPlugins call with refresh=true, but at this 380 // The call below will cause a GetPlugins call with refresh=true, but at this
408 // point we already know that the browser has refreshed its list, so disable 381 // point we already know that the browser has refreshed its list, so disable
409 // refresh temporarily to prevent each renderer process causing the list to be 382 // refresh temporarily to prevent each renderer process causing the list to be
410 // regenerated. 383 // regenerated.
411 plugin_refresh_allowed_ = false; 384 plugin_refresh_allowed_ = false;
412 WebKit::resetPluginCache(); 385 WebKit::resetPluginCache();
413 plugin_refresh_allowed_ = true; 386 plugin_refresh_allowed_ = true;
414 } 387 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698