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

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

Issue 6884001: Enforce no more includes through DEPS. I also added DEPS checking for gpu/plugin/worker directori... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 8 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
« no previous file with comments | « chrome/renderer/chrome_content_renderer_client.cc ('k') | content/gpu/DEPS » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/chrome_render_process_observer.h" 5 #include "chrome/renderer/chrome_render_process_observer.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/file_util.h" 8 #include "base/file_util.h"
9 #include "base/metrics/histogram.h" 9 #include "base/metrics/histogram.h"
10 #include "base/path_service.h" 10 #include "base/path_service.h"
11 #include "base/process_util.h" 11 #include "base/process_util.h"
12 #include "base/threading/platform_thread.h"
12 #include "chrome/common/chrome_paths.h" 13 #include "chrome/common/chrome_paths.h"
13 #include "chrome/common/chrome_switches.h" 14 #include "chrome/common/chrome_switches.h"
15 #include "chrome/common/extensions/extension_localization_peer.h"
14 #include "chrome/common/net/net_resource_provider.h" 16 #include "chrome/common/net/net_resource_provider.h"
15 #include "chrome/common/render_messages.h" 17 #include "chrome/common/render_messages.h"
16 #include "chrome/renderer/content_settings_observer.h" 18 #include "chrome/renderer/content_settings_observer.h"
19 #include "chrome/renderer/security_filter_peer.h"
20 #include "content/common/resource_dispatcher.h"
17 #include "content/common/view_messages.h" 21 #include "content/common/view_messages.h"
18 #include "content/renderer/render_thread.h" 22 #include "content/renderer/render_thread.h"
19 #include "content/renderer/render_view.h" 23 #include "content/renderer/render_view.h"
20 #include "content/renderer/render_view_visitor.h" 24 #include "content/renderer/render_view_visitor.h"
21 #include "crypto/nss_util.h" 25 #include "crypto/nss_util.h"
26 #include "net/base/net_errors.h"
22 #include "net/base/net_module.h" 27 #include "net/base/net_module.h"
23 #include "third_party/sqlite/sqlite3.h" 28 #include "third_party/sqlite/sqlite3.h"
24 #include "third_party/tcmalloc/chromium/src/google/malloc_extension.h" 29 #include "third_party/tcmalloc/chromium/src/google/malloc_extension.h"
25 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCache.h" 30 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCache.h"
26 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCrossOriginPreflig htResultCache.h" 31 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCrossOriginPreflig htResultCache.h"
27 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFontCache.h" 32 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFontCache.h"
28 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" 33 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
29 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" 34 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
30 #include "v8/include/v8.h" 35 #include "v8/include/v8.h"
36
31 #if defined(OS_WIN) 37 #if defined(OS_WIN)
32 #include "app/win/iat_patch_function.h" 38 #include "app/win/iat_patch_function.h"
33 #endif 39 #endif
34 40
41 #if defined(OS_MACOSX)
42 #include "base/eintr_wrapper.h"
43 #include "chrome/app/breakpad_mac.h"
44 #endif
45
35 using WebKit::WebCache; 46 using WebKit::WebCache;
36 using WebKit::WebCrossOriginPreflightResultCache; 47 using WebKit::WebCrossOriginPreflightResultCache;
37 using WebKit::WebFontCache; 48 using WebKit::WebFontCache;
38 49
39 namespace { 50 namespace {
40 51
52 static const unsigned int kCacheStatsDelayMS = 2000 /* milliseconds */;
53
54 class RenderResourceObserver : public ResourceDispatcher::Observer {
55 public:
56 RenderResourceObserver()
57 : ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {
58 }
59
60 virtual webkit_glue::ResourceLoaderBridge::Peer* OnRequestComplete(
61 webkit_glue::ResourceLoaderBridge::Peer* current_peer,
62 ResourceType::Type resource_type,
63 const net::URLRequestStatus& status) {
64 // Update the browser about our cache.
65 // Rate limit informing the host of our cache stats.
66 if (method_factory_.empty()) {
67 MessageLoop::current()->PostDelayedTask(
68 FROM_HERE,
69 method_factory_.NewRunnableMethod(
70 &RenderResourceObserver::InformHostOfCacheStats),
71 kCacheStatsDelayMS);
72 }
73
74 if (status.status() != net::URLRequestStatus::CANCELED ||
75 status.os_error() == net::ERR_ABORTED) {
76 return NULL;
77 }
78
79 // Resource canceled with a specific error are filtered.
80 return SecurityFilterPeer::CreateSecurityFilterPeerForDeniedRequest(
81 resource_type, current_peer, status.os_error());
82 }
83
84 virtual webkit_glue::ResourceLoaderBridge::Peer* OnReceivedResponse(
85 webkit_glue::ResourceLoaderBridge::Peer* current_peer,
86 const std::string& mime_type,
87 const GURL& url) {
88 return ExtensionLocalizationPeer::CreateExtensionLocalizationPeer(
89 current_peer, RenderThread::current(), mime_type, url);
90 }
91
92 private:
93 void InformHostOfCacheStats() {
94 WebCache::UsageStats stats;
95 WebCache::getUsageStats(&stats);
96 RenderThread::current()->Send(new ViewHostMsg_UpdatedCacheStats(stats));
97 }
98
99 ScopedRunnableMethodFactory<RenderResourceObserver> method_factory_;
100
101 DISALLOW_COPY_AND_ASSIGN(RenderResourceObserver);
102 };
103
104 class RenderViewContentSettingsSetter : public RenderViewVisitor {
105 public:
106 RenderViewContentSettingsSetter(const GURL& url,
107 const ContentSettings& content_settings)
108 : url_(url),
109 content_settings_(content_settings) {
110 }
111
112 virtual bool Visit(RenderView* render_view) {
113 if (GURL(render_view->webview()->mainFrame()->url()) == url_) {
114 ContentSettingsObserver::Get(render_view)->SetContentSettings(
115 content_settings_);
116 }
117 return true;
118 }
119
120 private:
121 GURL url_;
122 ContentSettings content_settings_;
123
124 DISALLOW_COPY_AND_ASSIGN(RenderViewContentSettingsSetter);
125 };
126
41 #if defined(OS_WIN) 127 #if defined(OS_WIN)
42
43 static app::win::IATPatchFunction g_iat_patch_createdca; 128 static app::win::IATPatchFunction g_iat_patch_createdca;
44 HDC WINAPI CreateDCAPatch(LPCSTR driver_name, 129 HDC WINAPI CreateDCAPatch(LPCSTR driver_name,
45 LPCSTR device_name, 130 LPCSTR device_name,
46 LPCSTR output, 131 LPCSTR output,
47 const void* init_data) { 132 const void* init_data) {
48 DCHECK(std::string("DISPLAY") == std::string(driver_name)); 133 DCHECK(std::string("DISPLAY") == std::string(driver_name));
49 DCHECK(!device_name); 134 DCHECK(!device_name);
50 DCHECK(!output); 135 DCHECK(!output);
51 DCHECK(!init_data); 136 DCHECK(!init_data);
52 137
(...skipping 13 matching lines...) Expand all
66 151
67 LOGFONT logfont; 152 LOGFONT logfont;
68 if (GetObject(font, sizeof(LOGFONT), &logfont)) { 153 if (GetObject(font, sizeof(LOGFONT), &logfont)) {
69 std::vector<char> font_data; 154 std::vector<char> font_data;
70 if (RenderThread::current()->Send(new ViewHostMsg_PreCacheFont(logfont))) 155 if (RenderThread::current()->Send(new ViewHostMsg_PreCacheFont(logfont)))
71 rv = GetFontData(hdc, table, offset, buffer, length); 156 rv = GetFontData(hdc, table, offset, buffer, length);
72 } 157 }
73 } 158 }
74 return rv; 159 return rv;
75 } 160 }
161 #endif // OS_WIN
76 162
77 #endif 163 #if defined(OS_POSIX)
164 class SuicideOnChannelErrorFilter : public IPC::ChannelProxy::MessageFilter {
165 void OnChannelError() {
166 // On POSIX, at least, one can install an unload handler which loops
167 // forever and leave behind a renderer process which eats 100% CPU forever.
168 //
169 // This is because the terminate signals (ViewMsg_ShouldClose and the error
170 // from the IPC channel) are routed to the main message loop but never
171 // processed (because that message loop is stuck in V8).
172 //
173 // One could make the browser SIGKILL the renderers, but that leaves open a
174 // large window where a browser failure (or a user, manually terminating
175 // the browser because "it's stuck") will leave behind a process eating all
176 // the CPU.
177 //
178 // So, we install a filter on the channel so that we can process this event
179 // here and kill the process.
78 180
79 class RenderViewContentSettingsSetter : public RenderViewVisitor { 181 #if defined(OS_MACOSX)
182 // TODO(viettrungluu): crbug.com/28547: The following is needed, as a
183 // stopgap, to avoid leaking due to not releasing Breakpad properly.
184 // TODO(viettrungluu): Investigate why this is being called.
185 if (IsCrashReporterEnabled()) {
186 VLOG(1) << "Cleaning up Breakpad.";
187 DestructCrashReporter();
188 } else {
189 VLOG(1) << "Breakpad not enabled; no clean-up needed.";
190 }
191 #endif // OS_MACOSX
192
193 _exit(0);
194 }
195 };
196 #endif // OS_POSIX
197
198 #if defined(OS_MACOSX)
199 // TODO(viettrungluu): crbug.com/28547: The following signal handling is needed,
200 // as a stopgap, to avoid leaking due to not releasing Breakpad properly.
201 // Without this problem, this could all be eliminated. Remove when Breakpad is
202 // fixed?
203 // TODO(viettrungluu): Code taken from browser_main.cc (with a bit of editing).
204 // The code should be properly shared (or this code should be eliminated).
205 int g_shutdown_pipe_write_fd = -1;
206
207 void SIGTERMHandler(int signal) {
208 RAW_CHECK(signal == SIGTERM);
209 RAW_LOG(INFO, "Handling SIGTERM in renderer.");
210
211 // Reinstall the default handler. We had one shot at graceful shutdown.
212 struct sigaction action;
213 memset(&action, 0, sizeof(action));
214 action.sa_handler = SIG_DFL;
215 CHECK(sigaction(signal, &action, NULL) == 0);
216
217 RAW_CHECK(g_shutdown_pipe_write_fd != -1);
218 size_t bytes_written = 0;
219 do {
220 int rv = HANDLE_EINTR(
221 write(g_shutdown_pipe_write_fd,
222 reinterpret_cast<const char*>(&signal) + bytes_written,
223 sizeof(signal) - bytes_written));
224 RAW_CHECK(rv >= 0);
225 bytes_written += rv;
226 } while (bytes_written < sizeof(signal));
227
228 RAW_LOG(INFO, "Wrote signal to shutdown pipe.");
229 }
230
231 class ShutdownDetector : public base::PlatformThread::Delegate {
80 public: 232 public:
81 RenderViewContentSettingsSetter(const GURL& url, 233 explicit ShutdownDetector(int shutdown_fd) : shutdown_fd_(shutdown_fd) {
82 const ContentSettings& content_settings) 234 CHECK(shutdown_fd_ != -1);
83 : url_(url),
84 content_settings_(content_settings) {
85 } 235 }
86 236
87 virtual bool Visit(RenderView* render_view) { 237 virtual void ThreadMain() {
88 if (GURL(render_view->webview()->mainFrame()->url()) == url_) { 238 int signal;
89 ContentSettingsObserver::Get(render_view)->SetContentSettings( 239 size_t bytes_read = 0;
90 content_settings_); 240 ssize_t ret;
241 do {
242 ret = HANDLE_EINTR(
243 read(shutdown_fd_,
244 reinterpret_cast<char*>(&signal) + bytes_read,
245 sizeof(signal) - bytes_read));
246 if (ret < 0) {
247 NOTREACHED() << "Unexpected error: " << strerror(errno);
248 break;
249 } else if (ret == 0) {
250 NOTREACHED() << "Unexpected closure of shutdown pipe.";
251 break;
252 }
253 bytes_read += ret;
254 } while (bytes_read < sizeof(signal));
255
256 if (bytes_read == sizeof(signal))
257 VLOG(1) << "Handling shutdown for signal " << signal << ".";
258 else
259 VLOG(1) << "Handling shutdown for unknown signal.";
260
261 // Clean up Breakpad if necessary.
262 if (IsCrashReporterEnabled()) {
263 VLOG(1) << "Cleaning up Breakpad.";
264 DestructCrashReporter();
265 } else {
266 VLOG(1) << "Breakpad not enabled; no clean-up needed.";
91 } 267 }
92 return true; 268
269 // Something went seriously wrong, so get out.
270 if (bytes_read != sizeof(signal)) {
271 LOG(WARNING) << "Failed to get signal. Quitting ungracefully.";
272 _exit(1);
273 }
274
275 // Re-raise the signal.
276 kill(getpid(), signal);
277
278 // The signal may be handled on another thread. Give that a chance to
279 // happen.
280 sleep(3);
281
282 // We really should be dead by now. For whatever reason, we're not. Exit
283 // immediately, with the exit status set to the signal number with bit 8
284 // set. On the systems that we care about, this exit status is what is
285 // normally used to indicate an exit by this signal's default handler.
286 // This mechanism isn't a de jure standard, but even in the worst case, it
287 // should at least result in an immediate exit.
288 LOG(WARNING) << "Still here, exiting really ungracefully.";
289 _exit(signal | (1 << 7));
93 } 290 }
94 291
95 private: 292 private:
96 GURL url_; 293 const int shutdown_fd_;
97 ContentSettings content_settings_;
98 294
99 DISALLOW_COPY_AND_ASSIGN(RenderViewContentSettingsSetter); 295 DISALLOW_COPY_AND_ASSIGN(ShutdownDetector);
100 }; 296 };
297 #endif // OS_MACOSX
101 298
102 } // namespace 299 } // namespace
103 300
104 bool ChromeRenderProcessObserver::is_incognito_process_ = false; 301 bool ChromeRenderProcessObserver::is_incognito_process_ = false;
105 302
106 ChromeRenderProcessObserver::ChromeRenderProcessObserver() { 303 ChromeRenderProcessObserver::ChromeRenderProcessObserver() {
107 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 304 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
108
109 if (command_line.HasSwitch(switches::kEnableWatchdog)) { 305 if (command_line.HasSwitch(switches::kEnableWatchdog)) {
110 // TODO(JAR): Need to implement renderer IO msgloop watchdog. 306 // TODO(JAR): Need to implement renderer IO msgloop watchdog.
111 } 307 }
112 308
113 if (command_line.HasSwitch(switches::kDumpHistogramsOnExit)) { 309 if (command_line.HasSwitch(switches::kDumpHistogramsOnExit)) {
114 base::StatisticsRecorder::set_dump_on_exit(true); 310 base::StatisticsRecorder::set_dump_on_exit(true);
115 } 311 }
116 312
313 RenderThread* thread = RenderThread::current();
314 thread->resource_dispatcher()->set_observer(new RenderResourceObserver());
315
316 #if defined(OS_POSIX)
317 thread->AddFilter(new SuicideOnChannelErrorFilter());
318 #endif
319
320 #if defined(OS_MACOSX)
321 // TODO(viettrungluu): Code taken from browser_main.cc.
322 int pipefd[2];
323 int ret = pipe(pipefd);
324 if (ret < 0) {
325 PLOG(DFATAL) << "Failed to create pipe";
326 } else {
327 int shutdown_pipe_read_fd = pipefd[0];
328 g_shutdown_pipe_write_fd = pipefd[1];
329 const size_t kShutdownDetectorThreadStackSize = 4096;
330 if (!base::PlatformThread::CreateNonJoinable(
331 kShutdownDetectorThreadStackSize,
332 new ShutdownDetector(shutdown_pipe_read_fd))) {
333 LOG(DFATAL) << "Failed to create shutdown detector task.";
334 }
335 }
336
337 // crbug.com/28547: When Breakpad is in use, handle SIGTERM to avoid leaking
338 // Mach ports.
339 struct sigaction action;
340 memset(&action, 0, sizeof(action));
341 action.sa_handler = SIGTERMHandler;
342 CHECK(sigaction(SIGTERM, &action, NULL) == 0);
343 #endif
344
117 // Configure modules that need access to resources. 345 // Configure modules that need access to resources.
118 net::NetModule::SetResourceProvider(chrome_common_net::NetResourceProvider); 346 net::NetModule::SetResourceProvider(chrome_common_net::NetResourceProvider);
119 347
120 #if defined(OS_WIN) 348 #if defined(OS_WIN)
121 // Need to patch a few functions for font loading to work correctly. 349 // Need to patch a few functions for font loading to work correctly.
122 FilePath pdf; 350 FilePath pdf;
123 if (PathService::Get(chrome::FILE_PDF_PLUGIN, &pdf) && 351 if (PathService::Get(chrome::FILE_PDF_PLUGIN, &pdf) &&
124 file_util::PathExists(pdf)) { 352 file_util::PathExists(pdf)) {
125 g_iat_patch_createdca.Patch( 353 g_iat_patch_createdca.Patch(
126 pdf.value().c_str(), "gdi32.dll", "CreateDCA", CreateDCAPatch); 354 pdf.value().c_str(), "gdi32.dll", "CreateDCA", CreateDCAPatch);
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 // a new "delete everything" pass because object references make it difficult 466 // a new "delete everything" pass because object references make it difficult
239 // to free everything possible in just one pass. 467 // to free everything possible in just one pass.
240 while (!v8::V8::IdleNotification()) { 468 while (!v8::V8::IdleNotification()) {
241 } 469 }
242 470
243 #if (defined(OS_WIN) || defined(OS_LINUX)) && defined(USE_TCMALLOC) 471 #if (defined(OS_WIN) || defined(OS_LINUX)) && defined(USE_TCMALLOC)
244 // Tell tcmalloc to release any free pages it's still holding. 472 // Tell tcmalloc to release any free pages it's still holding.
245 MallocExtension::instance()->ReleaseFreeMemory(); 473 MallocExtension::instance()->ReleaseFreeMemory();
246 #endif 474 #endif
247 } 475 }
OLDNEW
« no previous file with comments | « chrome/renderer/chrome_content_renderer_client.cc ('k') | content/gpu/DEPS » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698