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