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

Side by Side Diff: chrome/browser/renderer_host/browser_render_process_host.cc

Issue 18460: * Revert "POSIX: Get render_process_host to build." (Closed)
Patch Set: Created 11 years, 11 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-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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 // Represents the browser side of the browser <--> renderer communication
6 // channel. There will be one RenderProcessHost per renderer process.
7
8 #include "chrome/browser/renderer_host/browser_render_process_host.h" 5 #include "chrome/browser/renderer_host/browser_render_process_host.h"
9 6
10 #include "build/build_config.h"
11
12 #include <algorithm> 7 #include <algorithm>
13 #include <sstream> 8 #include <sstream>
14 #include <vector> 9 #include <vector>
15 10
16 #include "base/command_line.h" 11 #include "base/command_line.h"
17 #include "base/debug_util.h" 12 #include "base/debug_util.h"
18 #include "base/file_util.h" 13 #include "base/file_util.h"
19 #include "base/logging.h" 14 #include "base/logging.h"
20 #include "base/path_service.h" 15 #include "base/path_service.h"
21 #include "base/process_util.h" 16 #include "base/process_util.h"
22 #include "base/shared_memory.h" 17 #include "base/shared_memory.h"
23 #include "base/singleton.h" 18 #include "base/singleton.h"
24 #include "base/string_util.h" 19 #include "base/string_util.h"
25 #include "base/thread.h" 20 #include "base/thread.h"
21 #include "base/win_util.h"
26 #include "chrome/app/result_codes.h" 22 #include "chrome/app/result_codes.h"
23 #include "chrome/browser/browser.h"
27 #include "chrome/browser/browser_process.h" 24 #include "chrome/browser/browser_process.h"
28 #include "chrome/browser/cache_manager_host.h" 25 #include "chrome/browser/cache_manager_host.h"
29 #include "chrome/browser/extensions/user_script_master.h" 26 #include "chrome/browser/extensions/user_script_master.h"
30 #include "chrome/browser/history/history.h" 27 #include "chrome/browser/history/history.h"
31 #include "chrome/browser/plugin_service.h" 28 #include "chrome/browser/plugin_service.h"
32 #include "chrome/browser/render_widget_helper.h" 29 #include "chrome/browser/render_widget_helper.h"
30 #include "chrome/browser/render_view_host.h"
33 #include "chrome/browser/renderer_security_policy.h" 31 #include "chrome/browser/renderer_security_policy.h"
34 #include "chrome/browser/resource_message_filter.h" 32 #include "chrome/browser/resource_message_filter.h"
33 #include "chrome/browser/sandbox_policy.h"
35 #include "chrome/browser/spellchecker.h" 34 #include "chrome/browser/spellchecker.h"
36 #include "chrome/browser/visitedlink_master.h" 35 #include "chrome/browser/visitedlink_master.h"
36 #include "chrome/browser/tab_contents/web_contents.h"
37 #include "chrome/common/chrome_paths.h" 37 #include "chrome/common/chrome_paths.h"
38 #include "chrome/common/chrome_switches.h" 38 #include "chrome/common/chrome_switches.h"
39 #include "chrome/common/debug_flags.h" 39 #include "chrome/common/debug_flags.h"
40 #include "chrome/common/l10n_util.h" 40 #include "chrome/common/l10n_util.h"
41 #include "chrome/common/logging_chrome.h" 41 #include "chrome/common/logging_chrome.h"
42 #include "chrome/common/pref_names.h" 42 #include "chrome/common/pref_names.h"
43 #include "chrome/common/pref_service.h" 43 #include "chrome/common/pref_service.h"
44 #include "chrome/common/process_watcher.h" 44 #include "chrome/common/process_watcher.h"
45 #include "chrome/common/win_util.h"
45 #include "chrome/renderer/render_process.h" 46 #include "chrome/renderer/render_process.h"
46 #include "net/base/cookie_monster.h" 47 #include "net/base/cookie_monster.h"
47 #include "net/base/net_util.h" 48 #include "net/base/net_util.h"
48
49 #if defined(OS_WIN)
50 // TODO(port): see comment by the only usage of RenderViewHost in this file.
51 #include "chrome/browser/render_view_host.h"
52
53 // Once the above TODO is finished, then this block is all Windows-specific
54 // files.
55 #include "base/win_util.h"
56 #include "chrome/browser/sandbox_policy.h"
57 #include "chrome/common/win_util.h"
58 #include "common/win_util.h"
59 #include "sandbox/src/sandbox.h" 49 #include "sandbox/src/sandbox.h"
60 #endif
61 50
62 #include "SkBitmap.h" 51 #include "SkBitmap.h"
63 52
64 #include "generated_resources.h" 53 #include "generated_resources.h"
65 54
66 namespace { 55 namespace {
67 56
68 // ---------------------------------------------------------------------------- 57 // ----------------------------------------------------------------------------
69 58
70 class RendererMainThread : public base::Thread { 59 class RendererMainThread : public base::Thread {
71 public: 60 public:
72 explicit RendererMainThread(const std::wstring& channel_id) 61 explicit RendererMainThread(const std::wstring& channel_id)
73 : base::Thread("Chrome_InProcRendererThread"), 62 : base::Thread("Chrome_InProcRendererThread"),
74 channel_id_(channel_id) { 63 channel_id_(channel_id) {
75 } 64 }
76 65
77 protected: 66 protected:
78 virtual void Init() { 67 virtual void Init() {
79 #if defined(OS_WIN)
80 CoInitialize(NULL); 68 CoInitialize(NULL);
81 #endif
82 69
83 bool rv = RenderProcess::GlobalInit(channel_id_); 70 bool rv = RenderProcess::GlobalInit(channel_id_);
84 DCHECK(rv); 71 DCHECK(rv);
85 // It's a little lame to manually set this flag. But the single process 72 // It's a little lame to manually set this flag. But the single process
86 // RendererThread will receive the WM_QUIT. We don't need to assert on 73 // RendererThread will receive the WM_QUIT. We don't need to assert on
87 // this thread, so just force the flag manually. 74 // this thread, so just force the flag manually.
88 // If we want to avoid this, we could create the InProcRendererThread 75 // If we want to avoid this, we could create the InProcRendererThread
89 // directly with _beginthreadex() rather than using the Thread class. 76 // directly with _beginthreadex() rather than using the Thread class.
90 base::Thread::SetThreadWasQuitProperly(true); 77 base::Thread::SetThreadWasQuitProperly(true);
91 } 78 }
92 79
93 virtual void CleanUp() { 80 virtual void CleanUp() {
94 RenderProcess::GlobalCleanup(); 81 RenderProcess::GlobalCleanup();
95 82
96 #if defined(OS_WIN)
97 CoUninitialize(); 83 CoUninitialize();
98 #endif
99 } 84 }
100 85
101 private: 86 private:
102 std::wstring channel_id_; 87 std::wstring channel_id_;
103 }; 88 };
104 89
105 // Used for a View_ID where the renderer has not been attached yet 90 // Used for a View_ID where the renderer has not been attached yet
106 const int32 kInvalidViewID = -1; 91 const int32 kInvalidViewID = -1;
107 92
108 // Get the path to the renderer executable, which is the same as the 93 // Get the path to the renderer executable, which is the same as the
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 132
148 BrowserRenderProcessHost::~BrowserRenderProcessHost() { 133 BrowserRenderProcessHost::~BrowserRenderProcessHost() {
149 // Some tests hold BrowserRenderProcessHost in a scoped_ptr, so we must call 134 // Some tests hold BrowserRenderProcessHost in a scoped_ptr, so we must call
150 // Unregister here as well as in response to Release(). 135 // Unregister here as well as in response to Release().
151 Unregister(); 136 Unregister();
152 137
153 // We may have some unsent messages at this point, but that's OK. 138 // We may have some unsent messages at this point, but that's OK.
154 channel_.reset(); 139 channel_.reset();
155 140
156 if (process_.handle() && !run_renderer_in_process()) { 141 if (process_.handle() && !run_renderer_in_process()) {
142 watcher_.StopWatching();
157 ProcessWatcher::EnsureProcessTerminated(process_.handle()); 143 ProcessWatcher::EnsureProcessTerminated(process_.handle());
158 } 144 }
159 145
160 profile()->GetPrefs()->RemovePrefObserver(prefs::kBlockPopups, this); 146 profile()->GetPrefs()->RemovePrefObserver(prefs::kBlockPopups, this);
161 147
162 NotificationService::current()->RemoveObserver(this, 148 NotificationService::current()->RemoveObserver(this,
163 NOTIFY_USER_SCRIPTS_LOADED, NotificationService::AllSources()); 149 NOTIFY_USER_SCRIPTS_LOADED, NotificationService::AllSources());
164 } 150 }
165 151
166 // When we're started with the --start-renderers-manually flag, we pop up a
167 // modal dialog requesting the user manually start up a renderer.
168 // |cmd_line| is the command line to start the renderer with.
169 static void RunStartRenderersManuallyDialog(const CommandLine& cmd_line) {
170 #if defined(OS_WIN)
171 std::wstring message =
172 L"Please start a renderer process using:\n" +
173 cmd_line.command_line_string();
174
175 // We don't know the owner window for RenderProcessHost and therefore we
176 // pass a NULL HWND argument.
177 win_util::MessageBox(NULL,
178 message,
179 switches::kBrowserStartRenderersManually,
180 MB_OK);
181 #else
182 // TODO(port): refactor above code / pop up a message box here.
183 NOTIMPLEMENTED();
184 #endif
185 }
186
187 bool BrowserRenderProcessHost::Init() { 152 bool BrowserRenderProcessHost::Init() {
188 // calling Init() more than once does nothing, this makes it more convenient 153 // calling Init() more than once does nothing, this makes it more convenient
189 // for the view host which may not be sure in some cases 154 // for the view host which may not be sure in some cases
190 if (channel_.get()) 155 if (channel_.get())
191 return true; 156 return true;
192 157
193 // run the IPC channel on the shared IO thread. 158 // run the IPC channel on the shared IO thread.
194 base::Thread* io_thread = g_browser_process->io_thread(); 159 base::Thread* io_thread = g_browser_process->io_thread();
195 160
196 scoped_refptr<ResourceMessageFilter> resource_message_filter = 161 scoped_refptr<ResourceMessageFilter> resource_message_filter =
197 new ResourceMessageFilter(g_browser_process->resource_dispatcher_host(), 162 new ResourceMessageFilter(g_browser_process->resource_dispatcher_host(),
198 PluginService::GetInstance(), 163 PluginService::GetInstance(),
199 g_browser_process->print_job_manager(), 164 g_browser_process->print_job_manager(),
200 host_id(), 165 host_id(),
201 profile(), 166 profile(),
202 widget_helper_, 167 widget_helper_,
203 profile()->GetSpellChecker()); 168 profile()->GetSpellChecker());
204 169
205 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); 170 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
206 171
207 // setup IPC channel 172 // setup IPC channel
208 const std::wstring channel_id = GenerateRandomChannelID(this); 173 std::wstring channel_id = GenerateRandomChannelID(this);
209 channel_.reset( 174 channel_.reset(
210 new IPC::SyncChannel(channel_id, IPC::Channel::MODE_SERVER, this, 175 new IPC::SyncChannel(channel_id, IPC::Channel::MODE_SERVER, this,
211 resource_message_filter, 176 resource_message_filter,
212 io_thread->message_loop(), true, 177 io_thread->message_loop(), true,
213 g_browser_process->shutdown_event())); 178 g_browser_process->shutdown_event()));
214 // As a preventive mesure, we DCHECK if someone sends a synchronous message 179 // As a preventive mesure, we DCHECK if someone sends a synchronous message
215 // with no time-out, which in the context of the browser process we should not 180 // with no time-out, which in the context of the browser process we should not
216 // be doing. 181 // be doing.
217 channel_->set_sync_messages_with_no_timeout_allowed(false); 182 channel_->set_sync_messages_with_no_timeout_allowed(false);
218 183
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 switches::kMessageLoopHistogrammer, 219 switches::kMessageLoopHistogrammer,
255 switches::kEnableDCHECK, 220 switches::kEnableDCHECK,
256 switches::kSilentDumpOnDCHECK, 221 switches::kSilentDumpOnDCHECK,
257 switches::kDisablePopupBlocking, 222 switches::kDisablePopupBlocking,
258 switches::kUseLowFragHeapCrt, 223 switches::kUseLowFragHeapCrt,
259 switches::kGearsInRenderer, 224 switches::kGearsInRenderer,
260 switches::kEnableUserScripts, 225 switches::kEnableUserScripts,
261 switches::kEnableVideo, 226 switches::kEnableVideo,
262 }; 227 };
263 228
264 for (size_t i = 0; i < arraysize(switch_names); ++i) { 229 for (int i = 0; i < arraysize(switch_names); ++i) {
265 if (browser_command_line.HasSwitch(switch_names[i])) { 230 if (browser_command_line.HasSwitch(switch_names[i])) {
266 cmd_line.AppendSwitchWithValue(switch_names[i], 231 cmd_line.AppendSwitchWithValue(switch_names[i],
267 browser_command_line.GetSwitchValue(switch_names[i])); 232 browser_command_line.GetSwitchValue(switch_names[i]));
268 } 233 }
269 } 234 }
270 235
271 // Pass on the browser locale. 236 // Pass on the browser locale.
272 const std::wstring locale = g_browser_process->GetApplicationLocale(); 237 const std::wstring locale = g_browser_process->GetApplicationLocale();
273 cmd_line.AppendSwitchWithValue(switches::kLang, locale); 238 cmd_line.AppendSwitchWithValue(switches::kLang, locale);
274 239
275 bool in_sandbox = !browser_command_line.HasSwitch(switches::kNoSandbox); 240 bool in_sandbox = !browser_command_line.HasSwitch(switches::kNoSandbox);
276 if (browser_command_line.HasSwitch(switches::kInProcessPlugins)) { 241 if (browser_command_line.HasSwitch(switches::kInProcessPlugins)) {
277 // In process plugins won't work if the sandbox is enabled. 242 // In process plugins won't work if the sandbox is enabled.
278 in_sandbox = false; 243 in_sandbox = false;
279 } 244 }
280 245
281 #if defined(OS_WIN)
282 bool child_needs_help = 246 bool child_needs_help =
283 DebugFlags::ProcessDebugFlags(&cmd_line, 247 DebugFlags::ProcessDebugFlags(&cmd_line,
284 DebugFlags::RENDERER, 248 DebugFlags::RENDERER,
285 in_sandbox); 249 in_sandbox);
286 #endif
287
288 cmd_line.AppendSwitchWithValue(switches::kProcessType, 250 cmd_line.AppendSwitchWithValue(switches::kProcessType,
289 switches::kRendererProcess); 251 switches::kRendererProcess);
290 252
291 cmd_line.AppendSwitchWithValue(switches::kProcessChannelID, 253 cmd_line.AppendSwitchWithValue(switches::kProcessChannelID,
292 channel_id); 254 channel_id);
293 255
294 const std::wstring& profile_path = 256 const std::wstring& profile_path =
295 browser_command_line.GetSwitchValue(switches::kUserDataDir); 257 browser_command_line.GetSwitchValue(switches::kUserDataDir);
296 if (!profile_path.empty()) 258 if (!profile_path.empty())
297 cmd_line.AppendSwitchWithValue(switches::kUserDataDir, 259 cmd_line.AppendSwitchWithValue(switches::kUserDataDir,
(...skipping 14 matching lines...) Expand all
312 // 274 //
313 // TODO: We should consider how to better cleanup threads on exit. 275 // TODO: We should consider how to better cleanup threads on exit.
314 base::Thread *render_thread = new RendererMainThread(channel_id); 276 base::Thread *render_thread = new RendererMainThread(channel_id);
315 base::Thread::Options options; 277 base::Thread::Options options;
316 options.message_loop_type = MessageLoop::TYPE_IO; 278 options.message_loop_type = MessageLoop::TYPE_IO;
317 render_thread->StartWithOptions(options); 279 render_thread->StartWithOptions(options);
318 } else { 280 } else {
319 if (g_browser_process->local_state() && 281 if (g_browser_process->local_state() &&
320 g_browser_process->local_state()->GetBoolean( 282 g_browser_process->local_state()->GetBoolean(
321 prefs::kStartRenderersManually)) { 283 prefs::kStartRenderersManually)) {
322 RunStartRenderersManuallyDialog(cmd_line); 284 std::wstring message =
285 L"Please start a renderer process using:\n" +
286 cmd_line.command_line_string();
287
288 // We don't know the owner window for BrowserRenderProcessHost and therefo re we
289 // pass a NULL HWND argument.
290 win_util::MessageBox(NULL,
291 message,
292 switches::kBrowserStartRenderersManually,
293 MB_OK);
323 } else { 294 } else {
324 #if defined(OS_WIN)
325 if (in_sandbox) { 295 if (in_sandbox) {
326 // spawn the child process in the sandbox 296 // spawn the child process in the sandbox
327 sandbox::BrokerServices* broker_service = 297 sandbox::BrokerServices* broker_service =
328 g_browser_process->broker_services(); 298 g_browser_process->broker_services();
329 299
330 sandbox::ResultCode result; 300 sandbox::ResultCode result;
331 PROCESS_INFORMATION target = {0}; 301 PROCESS_INFORMATION target = {0};
332 sandbox::TargetPolicy* policy = broker_service->CreatePolicy(); 302 sandbox::TargetPolicy* policy = broker_service->CreatePolicy();
333 policy->SetJobLevel(sandbox::JOB_LOCKDOWN, 0); 303 policy->SetJobLevel(sandbox::JOB_LOCKDOWN, 0);
334 304
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 Details<bool>(&on_sandbox_desktop)); 355 Details<bool>(&on_sandbox_desktop));
386 356
387 ResumeThread(target.hThread); 357 ResumeThread(target.hThread);
388 CloseHandle(target.hThread); 358 CloseHandle(target.hThread);
389 process_.set_handle(target.hProcess); 359 process_.set_handle(target.hProcess);
390 360
391 // Help the process a little. It can't start the debugger by itself if 361 // Help the process a little. It can't start the debugger by itself if
392 // the process is in a sandbox. 362 // the process is in a sandbox.
393 if (child_needs_help) 363 if (child_needs_help)
394 DebugUtil::SpawnDebuggerOnProcess(target.dwProcessId); 364 DebugUtil::SpawnDebuggerOnProcess(target.dwProcessId);
395 } else 365 } else {
396 #endif // OS_WIN and sandbox
397 {
398 #if defined(OS_WIN)
399 // spawn child process 366 // spawn child process
400 base::ProcessHandle process = 0; 367 HANDLE process;
401 // TODO(port): LaunchApp is actually no good on POSIX when
402 // we've constructed the command line as we have here, as the above
403 // calls all append to a single string while LaunchApp reaches in to
404 // the argv array. CommandLine should be fixed, but once it is, this
405 // code will be correct.
406 if (!base::LaunchApp(cmd_line, false, false, &process)) 368 if (!base::LaunchApp(cmd_line, false, false, &process))
407 return false; 369 return false;
408 process_.set_handle(process); 370 process_.set_handle(process);
409 #endif
410 } 371 }
372
373 watcher_.StartWatching(process_.handle(), this);
411 } 374 }
412 } 375 }
413 376
414 // Now that the process is created, set it's backgrounding accordingly. 377 // Now that the process is created, set it's backgrounding accordingly.
415 SetBackgrounded(backgrounded_); 378 SetBackgrounded(backgrounded_);
416 379
417 InitVisitedLinks(); 380 InitVisitedLinks();
418 InitUserScripts(); 381 InitUserScripts();
419 382
420 if (max_page_id_ != -1) 383 if (max_page_id_ != -1)
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
534 channel_->Send(new ViewMsg_UserScripts_NewScripts(handle_for_process)); 497 channel_->Send(new ViewMsg_UserScripts_NewScripts(handle_for_process));
535 } 498 }
536 } 499 }
537 500
538 bool BrowserRenderProcessHost::FastShutdownIfPossible() { 501 bool BrowserRenderProcessHost::FastShutdownIfPossible() {
539 if (!process_.handle()) 502 if (!process_.handle())
540 return false; // Render process is probably crashed. 503 return false; // Render process is probably crashed.
541 if (BrowserRenderProcessHost::run_renderer_in_process()) 504 if (BrowserRenderProcessHost::run_renderer_in_process())
542 return false; // Since process mode can't do fast shutdown. 505 return false; // Since process mode can't do fast shutdown.
543 506
544 #if defined(OS_WIN)
545 // Test if there's an unload listener 507 // Test if there's an unload listener
546 BrowserRenderProcessHost::listeners_iterator iter; 508 BrowserRenderProcessHost::listeners_iterator iter;
547 // NOTE: This is a bit dangerous. We know that for now, listeners are 509 // NOTE: This is a bit dangerous. We know that for now, listeners are
548 // always RenderWidgetHosts. But in theory, they don't have to be. 510 // always RenderWidgetHosts. But in theory, they don't have to be.
549 for (iter = listeners_begin(); iter != listeners_end(); ++iter) { 511 for (iter = listeners_begin(); iter != listeners_end(); ++iter) {
550 RenderWidgetHost* widget = static_cast<RenderWidgetHost*>(iter->second); 512 RenderWidgetHost* widget = static_cast<RenderWidgetHost*>(iter->second);
551 DCHECK(widget); 513 DCHECK(widget);
552 if (!widget || !widget->IsRenderView()) 514 if (!widget || !widget->IsRenderView())
553 continue; 515 continue;
554 RenderViewHost* rvh = static_cast<RenderViewHost*>(widget); 516 RenderViewHost* rvh = static_cast<RenderViewHost*>(widget);
555 if (!rvh->CanTerminate()) { 517 if (!rvh->CanTerminate()) {
556 // NOTE: It's possible that an onunload listener may be installed 518 // NOTE: It's possible that an onunload listener may be installed
557 // while we're shutting down, so there's a small race here. Given that 519 // while we're shutting down, so there's a small race here. Given that
558 // the window is small, it's unlikely that the web page has much 520 // the window is small, it's unlikely that the web page has much
559 // state that will be lost by not calling its unload handlers properly. 521 // state that will be lost by not calling its unload handlers properly.
560 return false; 522 return false;
561 } 523 }
562 } 524 }
563 #else
564 // TODO(port): the above is the only reason this file pulls in
565 // RenderWidgetHost and RenderViewHost.
566 // Perhaps IPC::Channel::Listener needs another method like CanTerminate()?
567 // No matter what, some abstractions are getting broken here...
568 NOTIMPLEMENTED();
569 #endif
570 525
571 // Otherwise, we're allowed to just terminate the process. Using exit code 0 526 // Otherwise, we're allowed to just terminate the process. Using exit code 0
572 // means that UMA won't treat this as a renderer crash. 527 // means that UMA won't treat this as a renderer crash.
573 process_.Terminate(ResultCodes::NORMAL_EXIT); 528 process_.Terminate(ResultCodes::NORMAL_EXIT);
574 return true; 529 return true;
575 } 530 }
576 531
577 bool BrowserRenderProcessHost::Send(IPC::Message* msg) { 532 bool BrowserRenderProcessHost::Send(IPC::Message* msg) {
578 if (!channel_.get()) { 533 if (!channel_.get()) {
579 delete msg; 534 delete msg;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
612 Send(reply); 567 Send(reply);
613 } 568 }
614 return; 569 return;
615 } 570 }
616 listener->OnMessageReceived(msg); 571 listener->OnMessageReceived(msg);
617 } 572 }
618 573
619 void BrowserRenderProcessHost::OnChannelConnected(int32 peer_pid) { 574 void BrowserRenderProcessHost::OnChannelConnected(int32 peer_pid) {
620 // process_ is not NULL if we created the renderer process 575 // process_ is not NULL if we created the renderer process
621 if (!process_.handle()) { 576 if (!process_.handle()) {
622 if (base::GetCurrentProcId() == peer_pid) { 577 if (GetCurrentProcessId() == peer_pid) {
623 // We are in single-process mode. In theory we should have access to 578 // We are in single-process mode. In theory we should have access to
624 // ourself but it may happen that we don't. 579 // ourself but it may happen that we don't.
625 process_.set_handle(base::GetCurrentProcessHandle()); 580 process_.set_handle(GetCurrentProcess());
626 } else { 581 } else {
627 #if defined(OS_WIN)
628 // Request MAXIMUM_ALLOWED to match the access a handle 582 // Request MAXIMUM_ALLOWED to match the access a handle
629 // returned by CreateProcess() has to the process object. 583 // returned by CreateProcess() has to the process object.
630 process_.set_handle(OpenProcess(MAXIMUM_ALLOWED, FALSE, peer_pid)); 584 process_.set_handle(OpenProcess(MAXIMUM_ALLOWED, FALSE, peer_pid));
631 #elif defined(OS_POSIX)
632 // ProcessHandle is just a pid.
633 process_.set_handle(peer_pid);
634 #endif
635 DCHECK(process_.handle()); 585 DCHECK(process_.handle());
586 watcher_.StartWatching(process_.handle(), this);
636 } 587 }
637 } else { 588 } else {
638 // Need to verify that the peer_pid is actually the process we know, if 589 // Need to verify that the peer_pid is actually the process we know, if
639 // it is not, we need to panic now. See bug 1002150. 590 // it is not, we need to panic now. See bug 1002150.
640 CHECK(peer_pid == process_.pid()); 591 CHECK(peer_pid == process_.pid());
641 } 592 }
642 } 593 }
643 594
644 // Static. This function can be called from the IO Thread or from the UI thread. 595 // Static. This function can be called from the IO Thread or from the UI thread.
645 void BrowserRenderProcessHost::BadMessageTerminateProcess(uint16 msg_type, 596 void BrowserRenderProcessHost::BadMessageTerminateProcess(uint16 msg_type,
646 base::ProcessHandle pr ocess) { 597 HANDLE process) {
647 LOG(ERROR) << "bad message " << msg_type << " terminating renderer."; 598 LOG(ERROR) << "bad message " << msg_type << " terminating renderer.";
648 if (BrowserRenderProcessHost::run_renderer_in_process()) { 599 if (BrowserRenderProcessHost::run_renderer_in_process()) {
649 // In single process mode it is better if we don't suicide but just crash. 600 // In single process mode it is better if we don't suicide but just crash.
650 CHECK(false); 601 CHECK(false);
651 } 602 }
652 NOTREACHED(); 603 NOTREACHED();
653 base::KillProcess(process, ResultCodes::KILLED_BAD_MESSAGE, false); 604 ::TerminateProcess(process, ResultCodes::KILLED_BAD_MESSAGE);
654 } 605 }
655 606
656 void BrowserRenderProcessHost::OnChannelError() { 607 // indicates the renderer process has exited
657 // Our child process has died. If we didn't expect it, it's a crash. 608 void BrowserRenderProcessHost::OnObjectSignaled(HANDLE object) {
658 // In any case, we need to let everyone know it's gone.
659
660 DCHECK(process_.handle()); 609 DCHECK(process_.handle());
661 DCHECK(channel_.get()); 610 DCHECK(channel_.get());
662 base::ProcessHandle process = process_.handle(); 611 DCHECK_EQ(object, process_.handle());
663 612
664 bool clean_shutdown = !base::DidProcessCrash(process); 613 bool clean_shutdown = !base::DidProcessCrash(object);
665 614
666 process_.Close(); 615 process_.Close();
667 616
668 channel_.reset(); 617 channel_.reset();
669 618
670 if (!notified_termination_) { 619 if (!notified_termination_) {
671 // If |close_expected| is false, it means the renderer process went away 620 // If |close_expected| is false, it means the renderer process went away
672 // before the web views expected it; count it as a crash. 621 // before the web views expected it; count it as a crash.
673 NotificationService::current()->Notify(NOTIFY_RENDERER_PROCESS_TERMINATED, 622 NotificationService::current()->Notify(NOTIFY_RENDERER_PROCESS_TERMINATED,
674 Source<RenderProcessHost>(this), 623 Source<RenderProcessHost>(this),
675 Details<bool>(&clean_shutdown)); 624 Details<bool>(&clean_shutdown));
676 notified_termination_ = true; 625 notified_termination_ = true;
677 } 626 }
678 627
679 // This process should detach all the listeners, causing the object to be 628 // This process should detach all the listeners, causing the object to be
680 // deleted. We therefore need a stack copy of the web view list to avoid 629 // deleted. We therefore need a stack copy of the web view list to avoid
681 // crashing when checking for the termination condition the last time. 630 // crashing when checking for the termination condition the last time.
682 IDMap<IPC::Channel::Listener> local_listeners(listeners_); 631 IDMap<IPC::Channel::Listener> local_listeners(listeners_);
683 for (listeners_iterator i = local_listeners.begin(); 632 for (IDMap<IPC::Channel::Listener>::const_iterator i = local_listeners.begin() ;
684 i != local_listeners.end(); ++i) { 633 i != local_listeners.end(); ++i) {
685 i->second->OnMessageReceived(ViewHostMsg_RendererGone(i->first)); 634 i->second->OnMessageReceived(ViewHostMsg_RendererGone(i->first));
686 } 635 }
687 // at this point, this object should be deleted 636 // at this point, this object should be deleted
688 } 637 }
689 638
690 void BrowserRenderProcessHost::Unregister() { 639 void BrowserRenderProcessHost::Unregister() {
691 // RenderProcessHost::Unregister will clean up the host_id_, so we must 640 // RenderProcessHost::Unregister will clean up the host_id_, so we must
692 // do our cleanup that uses that variable before we call it. 641 // do our cleanup that uses that variable before we call it.
693 if (host_id() >= 0) { 642 if (host_id() >= 0) {
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
769 SendUserScriptsUpdate(shared_memory); 718 SendUserScriptsUpdate(shared_memory);
770 } 719 }
771 break; 720 break;
772 } 721 }
773 default: { 722 default: {
774 NOTREACHED(); 723 NOTREACHED();
775 break; 724 break;
776 } 725 }
777 } 726 }
778 } 727 }
779
780 std::wstring GenerateRandomChannelID(void* instance) {
781 // Note: the string must start with the current process id, this is how
782 // child processes determine the pid of the parent.
783 // Build the channel ID. This is composed of a unique identifier for the
784 // parent browser process, an identifier for the renderer/plugin instance,
785 // and a random component. We use a random component so that a hacked child
786 // process can't cause denial of service by causing future named pipe creation
787 // to fail.
788 return StringPrintf(L"%d.%x.%d",
789 base::GetCurrentProcId(), instance,
790 base::RandInt(0, std::numeric_limits<int>::max()));
791 }
OLDNEW
« no previous file with comments | « chrome/browser/renderer_host/browser_render_process_host.h ('k') | chrome/browser/renderer_host/render_process_host.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698