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

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

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