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

Side by Side Diff: chrome/browser/nacl_host/nacl_process_host.cc

Issue 10214007: Add an IPC channel between the NaCl loader process and the renderer. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 6 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/browser/nacl_host/nacl_process_host.h" 5 #include "chrome/browser/nacl_host/nacl_process_host.h"
6 6
7 #include <string> 7 #include <string>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 handles_for_sel_ldr->push_back(channel); 103 handles_for_sel_ldr->push_back(channel);
104 #endif 104 #endif
105 return true; 105 return true;
106 } 106 }
107 107
108 } // namespace 108 } // namespace
109 109
110 struct NaClProcessHost::NaClInternal { 110 struct NaClProcessHost::NaClInternal {
111 std::vector<nacl::Handle> sockets_for_renderer; 111 std::vector<nacl::Handle> sockets_for_renderer;
112 std::vector<nacl::Handle> sockets_for_sel_ldr; 112 std::vector<nacl::Handle> sockets_for_sel_ldr;
113 std::vector<nacl::FileDescriptor> handles_for_renderer;
113 }; 114 };
114 115
115 // ----------------------------------------------------------------------------- 116 // -----------------------------------------------------------------------------
116 117
117 NaClProcessHost::NaClProcessHost(const GURL& manifest_url, bool off_the_record) 118 NaClProcessHost::NaClProcessHost(const GURL& manifest_url, bool off_the_record)
118 : manifest_url_(manifest_url), 119 : manifest_url_(manifest_url),
119 #if defined(OS_WIN) 120 #if defined(OS_WIN)
120 process_launched_by_broker_(false), 121 process_launched_by_broker_(false),
121 #elif defined(OS_LINUX) 122 #elif defined(OS_LINUX)
122 wait_for_nacl_gdb_(false), 123 wait_for_nacl_gdb_(false),
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after
530 bool handled = true; 531 bool handled = true;
531 IPC_BEGIN_MESSAGE_MAP(NaClProcessHost, msg) 532 IPC_BEGIN_MESSAGE_MAP(NaClProcessHost, msg)
532 IPC_MESSAGE_HANDLER(NaClProcessMsg_QueryKnownToValidate, 533 IPC_MESSAGE_HANDLER(NaClProcessMsg_QueryKnownToValidate,
533 OnQueryKnownToValidate) 534 OnQueryKnownToValidate)
534 IPC_MESSAGE_HANDLER(NaClProcessMsg_SetKnownToValidate, 535 IPC_MESSAGE_HANDLER(NaClProcessMsg_SetKnownToValidate,
535 OnSetKnownToValidate) 536 OnSetKnownToValidate)
536 #if defined(OS_WIN) 537 #if defined(OS_WIN)
537 IPC_MESSAGE_HANDLER_DELAY_REPLY(NaClProcessMsg_AttachDebugExceptionHandler, 538 IPC_MESSAGE_HANDLER_DELAY_REPLY(NaClProcessMsg_AttachDebugExceptionHandler,
538 OnAttachDebugExceptionHandler) 539 OnAttachDebugExceptionHandler)
539 #endif 540 #endif
541 IPC_MESSAGE_HANDLER(NaClProcessHostMsg_PpapiChannelCreated,
542 OnPpapiChannelCreated)
540 IPC_MESSAGE_UNHANDLED(handled = false) 543 IPC_MESSAGE_UNHANDLED(handled = false)
541 IPC_END_MESSAGE_MAP() 544 IPC_END_MESSAGE_MAP()
542 return handled; 545 return handled;
543 } 546 }
544 547
545 void NaClProcessHost::OnProcessLaunched() { 548 void NaClProcessHost::OnProcessLaunched() {
546 if (!StartWithLaunchedProcess()) 549 if (!StartWithLaunchedProcess())
547 delete this; 550 delete this;
548 } 551 }
549 552
550 // Called when the NaClBrowser singleton has been fully initialized. 553 // Called when the NaClBrowser singleton has been fully initialized.
551 void NaClProcessHost::OnResourcesReady() { 554 void NaClProcessHost::OnResourcesReady() {
552 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); 555 NaClBrowser* nacl_browser = NaClBrowser::GetInstance();
553 if (!nacl_browser->IsReady() || !SendStart()) { 556 if (!nacl_browser->IsReady() || !SendStart()) {
554 DLOG(ERROR) << "Cannot launch NaCl process"; 557 DLOG(ERROR) << "Cannot launch NaCl process";
555 delete this; 558 delete this;
556 } 559 }
557 } 560 }
558 561
559 bool NaClProcessHost::ReplyToRenderer() { 562 bool NaClProcessHost::SendStart() {
Mark Seaborn 2012/06/20 19:24:40 Why do you need to merge ReplyToRenderer() and Sta
bbudge 2012/06/21 00:00:46 I merged these because we now have to wait for the
Mark Seaborn 2012/06/21 15:30:03 I understand why you've done it, but I don't think
bbudge 2012/06/21 18:16:53 Done. Good idea, it's a much smaller change this w
560 std::vector<nacl::FileDescriptor> handles_for_renderer;
561 for (size_t i = 0; i < internal_->sockets_for_renderer.size(); i++) { 563 for (size_t i = 0; i < internal_->sockets_for_renderer.size(); i++) {
562 #if defined(OS_WIN) 564 #if defined(OS_WIN)
563 // Copy the handle into the renderer process. 565 // Copy the handle into the renderer process.
564 HANDLE handle_in_renderer; 566 HANDLE handle_in_renderer;
565 if (!DuplicateHandle(base::GetCurrentProcessHandle(), 567 if (!DuplicateHandle(base::GetCurrentProcessHandle(),
566 reinterpret_cast<HANDLE>( 568 reinterpret_cast<HANDLE>(
567 internal_->sockets_for_renderer[i]), 569 internal_->sockets_for_renderer[i]),
568 chrome_render_message_filter_->peer_handle(), 570 chrome_render_message_filter_->peer_handle(),
569 &handle_in_renderer, 571 &handle_in_renderer,
570 0, // Unused given DUPLICATE_SAME_ACCESS. 572 0, // Unused given DUPLICATE_SAME_ACCESS.
571 FALSE, 573 FALSE,
572 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) { 574 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) {
573 DLOG(ERROR) << "DuplicateHandle() failed"; 575 DLOG(ERROR) << "DuplicateHandle() failed";
574 return false; 576 return false;
575 } 577 }
576 handles_for_renderer.push_back( 578 internal_->handles_for_renderer.push_back(
577 reinterpret_cast<nacl::FileDescriptor>(handle_in_renderer)); 579 reinterpret_cast<nacl::FileDescriptor>(handle_in_renderer));
578 #else 580 #else
579 // No need to dup the imc_handle - we don't pass it anywhere else so 581 // No need to dup the imc_handle - we don't pass it anywhere else so
580 // it cannot be closed. 582 // it cannot be closed.
581 nacl::FileDescriptor imc_handle; 583 nacl::FileDescriptor imc_handle;
582 imc_handle.fd = internal_->sockets_for_renderer[i]; 584 imc_handle.fd = internal_->sockets_for_renderer[i];
583 imc_handle.auto_close = true; 585 imc_handle.auto_close = true;
584 handles_for_renderer.push_back(imc_handle); 586 internal_->handles_for_renderer.push_back(imc_handle);
585 #endif 587 #endif
586 } 588 }
587 589
590 const ChildProcessData& data = process_->GetData();
588 #if defined(OS_WIN) 591 #if defined(OS_WIN)
589 // If we are on 64-bit Windows, the NaCl process's sandbox is 592 // If we are on 64-bit Windows, the NaCl process's sandbox is
590 // managed by a different process from the renderer's sandbox. We 593 // managed by a different process from the renderer's sandbox. We
591 // need to inform the renderer's sandbox about the NaCl process so 594 // need to inform the renderer's sandbox about the NaCl process so
592 // that the renderer can send handles to the NaCl process using 595 // that the renderer can send handles to the NaCl process using
593 // BrokerDuplicateHandle(). 596 // BrokerDuplicateHandle().
594 if (RunningOnWOW64()) { 597 if (RunningOnWOW64()) {
595 if (!content::BrokerAddTargetPeer(process_->GetData().handle)) { 598 if (!content::BrokerAddTargetPeer(data.handle)) {
596 DLOG(ERROR) << "Failed to add NaCl process PID"; 599 DLOG(ERROR) << "Failed to add NaCl process PID";
597 return false; 600 return false;
598 } 601 }
599 } 602 }
600 #endif 603 #endif
601 604
602 ChromeViewHostMsg_LaunchNaCl::WriteReplyParams(
603 reply_msg_, handles_for_renderer);
604 chrome_render_message_filter_->Send(reply_msg_);
605 chrome_render_message_filter_ = NULL;
606 reply_msg_ = NULL;
607 internal_->sockets_for_renderer.clear();
Mark Seaborn 2012/06/20 19:24:40 Removing this call isn't quite right. If NaClProc
bbudge 2012/06/21 00:00:46 I'm adding a TODO to fix this. I think we should c
608 return true;
609 }
610
611 bool NaClProcessHost::StartNaClExecution() {
612 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); 605 NaClBrowser* nacl_browser = NaClBrowser::GetInstance();
613 606
614 nacl::NaClStartParams params; 607 nacl::NaClStartParams params;
615 params.validation_cache_enabled = nacl_browser->ValidationCacheIsEnabled(); 608 params.validation_cache_enabled = nacl_browser->ValidationCacheIsEnabled();
616 params.validation_cache_key = nacl_browser->GetValidationCacheKey(); 609 params.validation_cache_key = nacl_browser->GetValidationCacheKey();
617 params.version = chrome::VersionInfo().CreateVersionString(); 610 params.version = chrome::VersionInfo().CreateVersionString();
618 params.enable_exception_handling = enable_exception_handling_; 611 params.enable_exception_handling = enable_exception_handling_;
619 params.enable_debug_stub = 612 params.enable_debug_stub =
620 CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableNaClDebug); 613 CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableNaClDebug);
614 params.enable_ipc_proxy = CommandLine::ForCurrentProcess()->HasSwitch(
615 switches::kEnableNaClIPCProxy);
621 616
622 base::PlatformFile irt_file = nacl_browser->IrtFile(); 617 base::PlatformFile irt_file = nacl_browser->IrtFile();
623 CHECK_NE(irt_file, base::kInvalidPlatformFileValue); 618 CHECK_NE(irt_file, base::kInvalidPlatformFileValue);
624 619
625 const ChildProcessData& data = process_->GetData();
626 for (size_t i = 0; i < internal_->sockets_for_sel_ldr.size(); i++) { 620 for (size_t i = 0; i < internal_->sockets_for_sel_ldr.size(); i++) {
627 if (!ShareHandleToSelLdr(data.handle, 621 if (!ShareHandleToSelLdr(data.handle,
628 internal_->sockets_for_sel_ldr[i], true, 622 internal_->sockets_for_sel_ldr[i], true,
629 &params.handles)) { 623 &params.handles)) {
630 return false; 624 return false;
631 } 625 }
632 } 626 }
633 627
634 // Send over the IRT file handle. We don't close our own copy! 628 // Send over the IRT file handle. We don't close our own copy!
635 if (!ShareHandleToSelLdr(data.handle, irt_file, false, &params.handles)) 629 if (!ShareHandleToSelLdr(data.handle, irt_file, false, &params.handles))
(...skipping 15 matching lines...) Expand all
651 nacl::FileDescriptor memory_fd; 645 nacl::FileDescriptor memory_fd;
652 memory_fd.fd = dup(memory_buffer.handle().fd); 646 memory_fd.fd = dup(memory_buffer.handle().fd);
653 if (memory_fd.fd < 0) { 647 if (memory_fd.fd < 0) {
654 DLOG(ERROR) << "Failed to dup() a file descriptor"; 648 DLOG(ERROR) << "Failed to dup() a file descriptor";
655 return false; 649 return false;
656 } 650 }
657 memory_fd.auto_close = true; 651 memory_fd.auto_close = true;
658 params.handles.push_back(memory_fd); 652 params.handles.push_back(memory_fd);
659 #endif 653 #endif
660 654
655 // The start message should only be sent once we are sure we won't delete
656 // ourselves.
661 process_->Send(new NaClProcessMsg_Start(params)); 657 process_->Send(new NaClProcessMsg_Start(params));
662 658
663 internal_->sockets_for_sel_ldr.clear(); 659 internal_->sockets_for_sel_ldr.clear();
660
661 // If we aren't creating the IPC channel, send the reply message without
662 // waiting for the NaCl process to signal that it's ready.
663 // TODO(bbudge) remove this after we switch to the IPC proxy.
664 if (!params.enable_ipc_proxy) {
665 OnPpapiChannelCreated(IPC::ChannelHandle());
666 }
667
664 return true; 668 return true;
665 } 669 }
666 670
667 bool NaClProcessHost::SendStart() { 671 void NaClProcessHost::OnPpapiChannelCreated(
668 return ReplyToRenderer() && StartNaClExecution(); 672 const IPC::ChannelHandle& channel_handle) {
673 // Now that the server end of the channel has been created, send the reply to
674 // the renderer.
675 base::ProcessId nacl_process_id = base::GetProcId(process_->GetData().handle);
676 ChromeViewHostMsg_LaunchNaCl::WriteReplyParams(
677 reply_msg_, internal_->handles_for_renderer, channel_handle,
678 nacl_process_id);
679 chrome_render_message_filter_->Send(reply_msg_);
680 chrome_render_message_filter_ = NULL;
681 reply_msg_ = NULL;
682
683 internal_->sockets_for_renderer.clear();
684 internal_->handles_for_renderer.clear();
669 } 685 }
670 686
671 bool NaClProcessHost::StartWithLaunchedProcess() { 687 bool NaClProcessHost::StartWithLaunchedProcess() {
672 #if defined(OS_LINUX) 688 #if defined(OS_LINUX)
673 if (wait_for_nacl_gdb_) { 689 if (wait_for_nacl_gdb_) {
674 if (LaunchNaClGdb(base::GetProcId(process_->GetData().handle))) { 690 if (LaunchNaClGdb(base::GetProcId(process_->GetData().handle))) {
675 // We will be called with wait_for_nacl_gdb_ = false once debugger is 691 // We will be called with wait_for_nacl_gdb_ = false once debugger is
676 // attached to the program. 692 // attached to the program.
677 return true; 693 return true;
678 } 694 }
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
765 } else { 781 } else {
766 NaClStartDebugExceptionHandlerThread( 782 NaClStartDebugExceptionHandlerThread(
767 process_handle.Take(), info, 783 process_handle.Take(), info,
768 base::MessageLoopProxy::current(), 784 base::MessageLoopProxy::current(),
769 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker, 785 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker,
770 weak_factory_.GetWeakPtr())); 786 weak_factory_.GetWeakPtr()));
771 return true; 787 return true;
772 } 788 }
773 } 789 }
774 #endif 790 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698