OLD | NEW |
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 | 5 // Represents the browser side of the browser <--> renderer communication |
6 // channel. There will be one RenderProcessHost per renderer process. | 6 // channel. There will be one RenderProcessHost per renderer process. |
7 | 7 |
8 #include "chrome/browser/render_process_host.h" | 8 #include "chrome/browser/render_process_host.h" |
9 | 9 |
10 #include <windows.h> | 10 #include <windows.h> |
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
415 CloseHandle(target.hThread); | 415 CloseHandle(target.hThread); |
416 process_.set_handle(target.hProcess); | 416 process_.set_handle(target.hProcess); |
417 | 417 |
418 // Help the process a little. It can't start the debugger by itself if | 418 // Help the process a little. It can't start the debugger by itself if |
419 // the process is in a sandbox. | 419 // the process is in a sandbox. |
420 if (child_needs_help) | 420 if (child_needs_help) |
421 DebugUtil::SpawnDebuggerOnProcess(target.dwProcessId); | 421 DebugUtil::SpawnDebuggerOnProcess(target.dwProcessId); |
422 } else { | 422 } else { |
423 // spawn child process | 423 // spawn child process |
424 HANDLE process; | 424 HANDLE process; |
425 if (!process_util::LaunchApp(cmd_line, false, false, &process)) | 425 if (!base::LaunchApp(cmd_line, false, false, &process)) |
426 return false; | 426 return false; |
427 process_.set_handle(process); | 427 process_.set_handle(process); |
428 } | 428 } |
429 | 429 |
430 watcher_.StartWatching(process_.handle(), this); | 430 watcher_.StartWatching(process_.handle(), this); |
431 } | 431 } |
432 } | 432 } |
433 | 433 |
434 // Now that the process is created, set it's backgrounding accordingly. | 434 // Now that the process is created, set it's backgrounding accordingly. |
435 SetBackgrounded(backgrounded_); | 435 SetBackgrounded(backgrounded_); |
436 | 436 |
437 InitVisitedLinks(); | 437 InitVisitedLinks(); |
438 InitGreasemonkeyScripts(); | 438 InitGreasemonkeyScripts(); |
439 | 439 |
440 if (max_page_id_ != -1) | 440 if (max_page_id_ != -1) |
441 channel_->Send(new ViewMsg_SetNextPageID(max_page_id_ + 1)); | 441 channel_->Send(new ViewMsg_SetNextPageID(max_page_id_ + 1)); |
442 | 442 |
443 return true; | 443 return true; |
444 } | 444 } |
445 | 445 |
446 HANDLE RenderProcessHost::GetRendererProcessHandle() { | 446 base::ProcessHandle RenderProcessHost::GetRendererProcessHandle() { |
447 HANDLE result = process_.handle(); | 447 if (run_renderer_in_process_) |
448 if (!result) { | 448 return base::Process::Current().handle(); |
449 // Renderer process can be null if it's started with the --single-process | 449 return process_.handle(); |
450 // flag. | |
451 result = GetCurrentProcess(); | |
452 } | |
453 return result; | |
454 } | 450 } |
455 | 451 |
456 void RenderProcessHost::InitVisitedLinks() { | 452 void RenderProcessHost::InitVisitedLinks() { |
457 VisitedLinkMaster* visitedlink_master = profile_->GetVisitedLinkMaster(); | 453 VisitedLinkMaster* visitedlink_master = profile_->GetVisitedLinkMaster(); |
458 if (!visitedlink_master) { | 454 if (!visitedlink_master) { |
459 return; | 455 return; |
460 } | 456 } |
461 | 457 |
462 SharedMemoryHandle handle_for_process = NULL; | 458 base::SharedMemoryHandle handle_for_process = NULL; |
463 visitedlink_master->ShareToProcess(GetRendererProcessHandle(), | 459 visitedlink_master->ShareToProcess(GetRendererProcessHandle(), |
464 &handle_for_process); | 460 &handle_for_process); |
465 DCHECK(handle_for_process); | 461 DCHECK(handle_for_process); |
466 if (handle_for_process) { | 462 if (handle_for_process) { |
467 channel_->Send(new ViewMsg_VisitedLink_NewTable(handle_for_process)); | 463 channel_->Send(new ViewMsg_VisitedLink_NewTable(handle_for_process)); |
468 } | 464 } |
469 } | 465 } |
470 | 466 |
471 void RenderProcessHost::InitGreasemonkeyScripts() { | 467 void RenderProcessHost::InitGreasemonkeyScripts() { |
472 CommandLine command_line; | 468 CommandLine command_line; |
(...skipping 15 matching lines...) Expand all Loading... |
488 if (!greasemonkey_master->ScriptsReady()) { | 484 if (!greasemonkey_master->ScriptsReady()) { |
489 // No scripts ready. :( | 485 // No scripts ready. :( |
490 return; | 486 return; |
491 } | 487 } |
492 | 488 |
493 // Update the renderer process with the current scripts. | 489 // Update the renderer process with the current scripts. |
494 SendGreasemonkeyScriptsUpdate(greasemonkey_master->GetSharedMemory()); | 490 SendGreasemonkeyScriptsUpdate(greasemonkey_master->GetSharedMemory()); |
495 } | 491 } |
496 | 492 |
497 void RenderProcessHost::SendGreasemonkeyScriptsUpdate( | 493 void RenderProcessHost::SendGreasemonkeyScriptsUpdate( |
498 SharedMemory *shared_memory) { | 494 base::SharedMemory *shared_memory) { |
499 SharedMemoryHandle handle_for_process = NULL; | 495 base::SharedMemoryHandle handle_for_process = NULL; |
500 shared_memory->ShareToProcess(GetRendererProcessHandle(), | 496 shared_memory->ShareToProcess(GetRendererProcessHandle(), |
501 &handle_for_process); | 497 &handle_for_process); |
502 DCHECK(handle_for_process); | 498 DCHECK(handle_for_process); |
503 if (handle_for_process) { | 499 if (handle_for_process) { |
504 channel_->Send(new ViewMsg_Greasemonkey_NewScripts(handle_for_process)); | 500 channel_->Send(new ViewMsg_Greasemonkey_NewScripts(handle_for_process)); |
505 } | 501 } |
506 } | 502 } |
507 | 503 |
508 void RenderProcessHost::Attach(IPC::Channel::Listener* listener, | 504 void RenderProcessHost::Attach(IPC::Channel::Listener* listener, |
509 int routing_id) { | 505 int routing_id) { |
(...skipping 19 matching lines...) Expand all Loading... |
529 Unregister(); | 525 Unregister(); |
530 MessageLoop::current()->DeleteSoon(FROM_HERE, this); | 526 MessageLoop::current()->DeleteSoon(FROM_HERE, this); |
531 } | 527 } |
532 } | 528 } |
533 | 529 |
534 void RenderProcessHost::ReportExpectingClose(int32 listener_id) { | 530 void RenderProcessHost::ReportExpectingClose(int32 listener_id) { |
535 listeners_expecting_close_.insert(listener_id); | 531 listeners_expecting_close_.insert(listener_id); |
536 } | 532 } |
537 | 533 |
538 bool RenderProcessHost::FastShutdownIfPossible() { | 534 bool RenderProcessHost::FastShutdownIfPossible() { |
539 HANDLE proc = process().handle(); | 535 if (!process_.handle()) |
540 if (!proc) | 536 return false; // Render process is probably crashed. |
541 return false; | |
542 // If we're in single process mode, do nothing. | |
543 if (RenderProcessHost::run_renderer_in_process()) | 537 if (RenderProcessHost::run_renderer_in_process()) |
544 return false; | 538 return false; // Since process mode can't do fast shutdown. |
545 | 539 |
546 // Test if there's an unload listener | 540 // Test if there's an unload listener |
547 RenderProcessHost::listeners_iterator iter; | 541 RenderProcessHost::listeners_iterator iter; |
548 // NOTE: This is a bit dangerous. We know that for now, listeners are | 542 // NOTE: This is a bit dangerous. We know that for now, listeners are |
549 // always RenderWidgetHosts. But in theory, they don't have to be. | 543 // always RenderWidgetHosts. But in theory, they don't have to be. |
550 for (iter = listeners_begin(); iter != listeners_end(); ++iter) { | 544 for (iter = listeners_begin(); iter != listeners_end(); ++iter) { |
551 RenderWidgetHost* widget = static_cast<RenderWidgetHost*>(iter->second); | 545 RenderWidgetHost* widget = static_cast<RenderWidgetHost*>(iter->second); |
552 DCHECK(widget); | 546 DCHECK(widget); |
553 if (!widget || !widget->IsRenderView()) | 547 if (!widget || !widget->IsRenderView()) |
554 continue; | 548 continue; |
555 RenderViewHost* rvh = static_cast<RenderViewHost*>(widget); | 549 RenderViewHost* rvh = static_cast<RenderViewHost*>(widget); |
556 if (rvh->HasUnloadListener()) { | 550 if (rvh->HasUnloadListener()) { |
557 // NOTE: It's possible that an onunload listener may be installed | 551 // NOTE: It's possible that an onunload listener may be installed |
558 // while we're shutting down, so there's a small race here. Given that | 552 // while we're shutting down, so there's a small race here. Given that |
559 // the window is small, it's unlikely that the web page has much | 553 // the window is small, it's unlikely that the web page has much |
560 // state that will be lost by not calling its unload handlers properly. | 554 // state that will be lost by not calling its unload handlers properly. |
561 return false; | 555 return false; |
562 } | 556 } |
563 } | 557 } |
564 // Otherwise, call TerminateProcess. Using exit code 0 means that UMA won't | 558 |
565 // treat this as a renderer crash. | 559 // Otherwise, we're allowed to just terminate the process. Using exit code 0 |
566 ::TerminateProcess(proc, ResultCodes::NORMAL_EXIT); | 560 // means that UMA won't treat this as a renderer crash. |
| 561 process_.Terminate(ResultCodes::NORMAL_EXIT); |
567 return true; | 562 return true; |
568 } | 563 } |
569 | 564 |
570 // Static. This function can be called from the IO Thread or from the UI thread. | 565 // Static. This function can be called from the IO Thread or from the UI thread. |
571 void RenderProcessHost::BadMessageTerminateProcess(uint16 msg_type, | 566 void RenderProcessHost::BadMessageTerminateProcess(uint16 msg_type, |
572 HANDLE process) { | 567 HANDLE process) { |
573 LOG(ERROR) << "bad message " << msg_type << " terminating renderer."; | 568 LOG(ERROR) << "bad message " << msg_type << " terminating renderer."; |
574 if (RenderProcessHost::run_renderer_in_process()) { | 569 if (RenderProcessHost::run_renderer_in_process()) { |
575 // In single process mode it is better if we don't suicide but just crash. | 570 // In single process mode it is better if we don't suicide but just crash. |
576 CHECK(false); | 571 CHECK(false); |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
644 CHECK(peer_pid == process_.pid()); | 639 CHECK(peer_pid == process_.pid()); |
645 } | 640 } |
646 } | 641 } |
647 | 642 |
648 // indicates the renderer process has exited | 643 // indicates the renderer process has exited |
649 void RenderProcessHost::OnObjectSignaled(HANDLE object) { | 644 void RenderProcessHost::OnObjectSignaled(HANDLE object) { |
650 DCHECK(process_.handle()); | 645 DCHECK(process_.handle()); |
651 DCHECK(channel_.get()); | 646 DCHECK(channel_.get()); |
652 DCHECK_EQ(object, process_.handle()); | 647 DCHECK_EQ(object, process_.handle()); |
653 | 648 |
654 bool clean_shutdown = !process_util::DidProcessCrash(object); | 649 bool clean_shutdown = !base::DidProcessCrash(object); |
655 | 650 |
656 process_.Close(); | 651 process_.Close(); |
657 | 652 |
658 channel_.reset(); | 653 channel_.reset(); |
659 | 654 |
660 if (!notified_termination_) { | 655 if (!notified_termination_) { |
661 // If |close_expected| is false, it means the renderer process went away | 656 // If |close_expected| is false, it means the renderer process went away |
662 // before the web views expected it; count it as a crash. | 657 // before the web views expected it; count it as a crash. |
663 NotificationService::current()->Notify(NOTIFY_RENDERER_PROCESS_TERMINATED, | 658 NotificationService::current()->Notify(NOTIFY_RENDERER_PROCESS_TERMINATED, |
664 Source<RenderProcessHost>(this), | 659 Source<RenderProcessHost>(this), |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
817 DCHECK(Source<PrefService>(source).ptr() == profile()->GetPrefs()); | 812 DCHECK(Source<PrefService>(source).ptr() == profile()->GetPrefs()); |
818 if (*pref_name_in == prefs::kBlockPopups) { | 813 if (*pref_name_in == prefs::kBlockPopups) { |
819 widget_helper_->set_block_popups( | 814 widget_helper_->set_block_popups( |
820 profile()->GetPrefs()->GetBoolean(prefs::kBlockPopups)); | 815 profile()->GetPrefs()->GetBoolean(prefs::kBlockPopups)); |
821 } else { | 816 } else { |
822 NOTREACHED() << "unexpected pref change notification" << *pref_name_in; | 817 NOTREACHED() << "unexpected pref change notification" << *pref_name_in; |
823 } | 818 } |
824 break; | 819 break; |
825 } | 820 } |
826 case NOTIFY_NEW_USER_SCRIPTS: { | 821 case NOTIFY_NEW_USER_SCRIPTS: { |
827 SharedMemory* shared_memory = Details<SharedMemory>(details).ptr(); | 822 base::SharedMemory* shared_memory = |
| 823 Details<base::SharedMemory>(details).ptr(); |
828 DCHECK(shared_memory); | 824 DCHECK(shared_memory); |
829 if (shared_memory) { | 825 if (shared_memory) { |
830 SendGreasemonkeyScriptsUpdate(shared_memory); | 826 SendGreasemonkeyScriptsUpdate(shared_memory); |
831 } | 827 } |
832 break; | 828 break; |
833 } | 829 } |
834 default: { | 830 default: { |
835 NOTREACHED(); | 831 NOTREACHED(); |
836 break; | 832 break; |
837 } | 833 } |
838 } | 834 } |
839 } | 835 } |
840 | 836 |
841 // static | 837 // static |
842 bool RenderProcessHost::ShouldTryToUseExistingProcessHost() { | 838 bool RenderProcessHost::ShouldTryToUseExistingProcessHost() { |
843 unsigned int renderer_process_count = | 839 unsigned int renderer_process_count = |
844 static_cast<unsigned int>(all_hosts.size()); | 840 static_cast<unsigned int>(all_hosts.size()); |
845 | 841 |
846 // NOTE: Sometimes it's necessary to create more render processes than | 842 // NOTE: Sometimes it's necessary to create more render processes than |
847 // GetMaxRendererProcessCount(), for instance when we want to create | 843 // GetMaxRendererProcessCount(), for instance when we want to create |
848 // a renderer process for a profile that has no existing renderers. | 844 // a renderer process for a profile that has no existing renderers. |
849 // This is OK in moderation, since the GetMaxRendererProcessCount() | 845 // This is OK in moderation, since the GetMaxRendererProcessCount() |
850 // is conservative. | 846 // is conservative. |
851 | 847 |
852 return run_renderer_in_process() || | 848 return run_renderer_in_process() || |
853 (renderer_process_count >= GetMaxRendererProcessCount()); | 849 (renderer_process_count >= GetMaxRendererProcessCount()); |
854 } | 850 } |
855 | 851 |
OLD | NEW |