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

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, 7 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) 118 NaClProcessHost::NaClProcessHost(const GURL& manifest_url)
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 392 matching lines...) Expand 10 before | Expand all | Expand 10 after
515 bool handled = true; 516 bool handled = true;
516 IPC_BEGIN_MESSAGE_MAP(NaClProcessHost, msg) 517 IPC_BEGIN_MESSAGE_MAP(NaClProcessHost, msg)
517 IPC_MESSAGE_HANDLER(NaClProcessMsg_QueryKnownToValidate, 518 IPC_MESSAGE_HANDLER(NaClProcessMsg_QueryKnownToValidate,
518 OnQueryKnownToValidate) 519 OnQueryKnownToValidate)
519 IPC_MESSAGE_HANDLER(NaClProcessMsg_SetKnownToValidate, 520 IPC_MESSAGE_HANDLER(NaClProcessMsg_SetKnownToValidate,
520 OnSetKnownToValidate) 521 OnSetKnownToValidate)
521 #if defined(OS_WIN) 522 #if defined(OS_WIN)
522 IPC_MESSAGE_HANDLER_DELAY_REPLY(NaClProcessMsg_AttachDebugExceptionHandler, 523 IPC_MESSAGE_HANDLER_DELAY_REPLY(NaClProcessMsg_AttachDebugExceptionHandler,
523 OnAttachDebugExceptionHandler) 524 OnAttachDebugExceptionHandler)
524 #endif 525 #endif
526 IPC_MESSAGE_HANDLER(NaClProcessHostMsg_PpapiChannelCreated,
527 OnPpapiChannelCreated)
525 IPC_MESSAGE_UNHANDLED(handled = false) 528 IPC_MESSAGE_UNHANDLED(handled = false)
526 IPC_END_MESSAGE_MAP() 529 IPC_END_MESSAGE_MAP()
527 return handled; 530 return handled;
528 } 531 }
529 532
530 void NaClProcessHost::OnProcessCrashed(int exit_code) { 533 void NaClProcessHost::OnProcessCrashed(int exit_code) {
531 std::string message = base::StringPrintf( 534 std::string message = base::StringPrintf(
532 "NaCl process exited with status %i (0x%x)", exit_code, exit_code); 535 "NaCl process exited with status %i (0x%x)", exit_code, exit_code);
533 LOG(ERROR) << message; 536 LOG(ERROR) << message;
534 } 537 }
535 538
536 void NaClProcessHost::OnProcessLaunched() { 539 void NaClProcessHost::OnProcessLaunched() {
537 if (!StartWithLaunchedProcess()) 540 if (!StartWithLaunchedProcess())
538 delete this; 541 delete this;
539 } 542 }
540 543
541 // The asynchronous attempt to get the IRT file open has completed. 544 // The asynchronous attempt to get the IRT file open has completed.
542 void NaClProcessHost::IrtReady() { 545 void NaClProcessHost::IrtReady() {
543 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); 546 NaClBrowser* nacl_browser = NaClBrowser::GetInstance();
544 if (!nacl_browser->IrtAvailable() || !SendStart()) { 547 if (!nacl_browser->IrtAvailable() || !SendStart()) {
545 DLOG(ERROR) << "Cannot launch NaCl process"; 548 DLOG(ERROR) << "Cannot launch NaCl process";
546 delete this; 549 delete this;
547 } 550 }
548 } 551 }
549 552
550 bool NaClProcessHost::ReplyToRenderer() { 553 bool NaClProcessHost::SendStart() {
551 std::vector<nacl::FileDescriptor> handles_for_renderer;
552 for (size_t i = 0; i < internal_->sockets_for_renderer.size(); i++) { 554 for (size_t i = 0; i < internal_->sockets_for_renderer.size(); i++) {
553 #if defined(OS_WIN) 555 #if defined(OS_WIN)
554 // Copy the handle into the renderer process. 556 // Copy the handle into the renderer process.
555 HANDLE handle_in_renderer; 557 HANDLE handle_in_renderer;
556 if (!DuplicateHandle(base::GetCurrentProcessHandle(), 558 if (!DuplicateHandle(base::GetCurrentProcessHandle(),
557 reinterpret_cast<HANDLE>( 559 reinterpret_cast<HANDLE>(
558 internal_->sockets_for_renderer[i]), 560 internal_->sockets_for_renderer[i]),
559 chrome_render_message_filter_->peer_handle(), 561 chrome_render_message_filter_->peer_handle(),
560 &handle_in_renderer, 562 &handle_in_renderer,
561 0, // Unused given DUPLICATE_SAME_ACCESS. 563 0, // Unused given DUPLICATE_SAME_ACCESS.
562 FALSE, 564 FALSE,
563 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) { 565 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) {
564 DLOG(ERROR) << "DuplicateHandle() failed"; 566 DLOG(ERROR) << "DuplicateHandle() failed";
565 return false; 567 return false;
566 } 568 }
567 handles_for_renderer.push_back( 569 internal_->handles_for_renderer.push_back(
568 reinterpret_cast<nacl::FileDescriptor>(handle_in_renderer)); 570 reinterpret_cast<nacl::FileDescriptor>(handle_in_renderer));
569 #else 571 #else
570 // No need to dup the imc_handle - we don't pass it anywhere else so 572 // No need to dup the imc_handle - we don't pass it anywhere else so
571 // it cannot be closed. 573 // it cannot be closed.
572 nacl::FileDescriptor imc_handle; 574 nacl::FileDescriptor imc_handle;
573 imc_handle.fd = internal_->sockets_for_renderer[i]; 575 imc_handle.fd = internal_->sockets_for_renderer[i];
574 imc_handle.auto_close = true; 576 imc_handle.auto_close = true;
575 handles_for_renderer.push_back(imc_handle); 577 internal_->handles_for_renderer.push_back(imc_handle);
576 #endif 578 #endif
577 } 579 }
578 580
581 const ChildProcessData& data = process_->GetData();
579 #if defined(OS_WIN) 582 #if defined(OS_WIN)
580 // If we are on 64-bit Windows, the NaCl process's sandbox is 583 // If we are on 64-bit Windows, the NaCl process's sandbox is
581 // managed by a different process from the renderer's sandbox. We 584 // managed by a different process from the renderer's sandbox. We
582 // need to inform the renderer's sandbox about the NaCl process so 585 // need to inform the renderer's sandbox about the NaCl process so
583 // that the renderer can send handles to the NaCl process using 586 // that the renderer can send handles to the NaCl process using
584 // BrokerDuplicateHandle(). 587 // BrokerDuplicateHandle().
585 if (RunningOnWOW64()) { 588 if (RunningOnWOW64()) {
586 if (!content::BrokerAddTargetPeer(process_->GetData().handle)) { 589 if (!content::BrokerAddTargetPeer(data.handle)) {
587 DLOG(ERROR) << "Failed to add NaCl process PID"; 590 DLOG(ERROR) << "Failed to add NaCl process PID";
588 return false; 591 return false;
589 } 592 }
590 } 593 }
591 #endif 594 #endif
592 595
593 ChromeViewHostMsg_LaunchNaCl::WriteReplyParams(
594 reply_msg_, handles_for_renderer);
595 chrome_render_message_filter_->Send(reply_msg_);
596 chrome_render_message_filter_ = NULL;
597 reply_msg_ = NULL;
598 internal_->sockets_for_renderer.clear();
599 return true;
600 }
601
602 bool NaClProcessHost::StartNaClExecution() {
603 NaClBrowser* nacl_browser = NaClBrowser::GetInstance(); 596 NaClBrowser* nacl_browser = NaClBrowser::GetInstance();
604 597
605 nacl::NaClStartParams params; 598 nacl::NaClStartParams params;
606 params.validation_cache_key = 599 params.validation_cache_key =
607 nacl_browser->validation_cache.GetValidationCacheKey(); 600 nacl_browser->validation_cache.GetValidationCacheKey();
608 params.version = chrome::VersionInfo().CreateVersionString(); 601 params.version = chrome::VersionInfo().CreateVersionString();
609 params.enable_exception_handling = enable_exception_handling_; 602 params.enable_exception_handling = enable_exception_handling_;
610 603
dmichael (off chromium) 2012/05/23 21:24:12 I think you need to set params.enable_ipc_proxy he
bbudge 2012/05/23 21:42:20 Done. Thanks for tracking this down.
611 base::PlatformFile irt_file = nacl_browser->IrtFile(); 604 base::PlatformFile irt_file = nacl_browser->IrtFile();
612 CHECK_NE(irt_file, base::kInvalidPlatformFileValue); 605 CHECK_NE(irt_file, base::kInvalidPlatformFileValue);
613 606
614 const ChildProcessData& data = process_->GetData();
615 for (size_t i = 0; i < internal_->sockets_for_sel_ldr.size(); i++) { 607 for (size_t i = 0; i < internal_->sockets_for_sel_ldr.size(); i++) {
616 if (!ShareHandleToSelLdr(data.handle, 608 if (!ShareHandleToSelLdr(data.handle,
617 internal_->sockets_for_sel_ldr[i], true, 609 internal_->sockets_for_sel_ldr[i], true,
618 &params.handles)) { 610 &params.handles)) {
619 return false; 611 return false;
620 } 612 }
621 } 613 }
622 614
623 // Send over the IRT file handle. We don't close our own copy! 615 // Send over the IRT file handle. We don't close our own copy!
624 if (!ShareHandleToSelLdr(data.handle, irt_file, false, &params.handles)) 616 if (!ShareHandleToSelLdr(data.handle, irt_file, false, &params.handles))
(...skipping 15 matching lines...) Expand all
640 nacl::FileDescriptor memory_fd; 632 nacl::FileDescriptor memory_fd;
641 memory_fd.fd = dup(memory_buffer.handle().fd); 633 memory_fd.fd = dup(memory_buffer.handle().fd);
642 if (memory_fd.fd < 0) { 634 if (memory_fd.fd < 0) {
643 DLOG(ERROR) << "Failed to dup() a file descriptor"; 635 DLOG(ERROR) << "Failed to dup() a file descriptor";
644 return false; 636 return false;
645 } 637 }
646 memory_fd.auto_close = true; 638 memory_fd.auto_close = true;
647 params.handles.push_back(memory_fd); 639 params.handles.push_back(memory_fd);
648 #endif 640 #endif
649 641
642 // The start message should only be sent once we are sure we won't delete
643 // ourselves.
650 process_->Send(new NaClProcessMsg_Start(params)); 644 process_->Send(new NaClProcessMsg_Start(params));
651 645
652 internal_->sockets_for_sel_ldr.clear(); 646 internal_->sockets_for_sel_ldr.clear();
647
648 // If we aren't creating the IPC channel, send the reply message without
649 // waiting for the NaCl process to signal that it's ready.
650 if (!CommandLine::ForCurrentProcess()->HasSwitch(
651 switches::kEnableNaClIPCProxy)) {
652 OnPpapiChannelCreated(IPC::ChannelHandle());
653 }
654
653 return true; 655 return true;
654 } 656 }
655 657
656 bool NaClProcessHost::SendStart() { 658 void NaClProcessHost::OnPpapiChannelCreated(
657 return ReplyToRenderer() && StartNaClExecution(); 659 const IPC::ChannelHandle& channel_handle) {
660 // Now that the server end of the channel has been created, send the reply to
661 // the renderer.
662 base::ProcessId nacl_process_id = base::GetProcId(process_->GetData().handle);
663 ChromeViewHostMsg_LaunchNaCl::WriteReplyParams(
664 reply_msg_, internal_->handles_for_renderer, channel_handle,
665 nacl_process_id);
666 chrome_render_message_filter_->Send(reply_msg_);
667 chrome_render_message_filter_ = NULL;
668 reply_msg_ = NULL;
669
670 internal_->sockets_for_renderer.clear();
671 internal_->handles_for_renderer.clear();
658 } 672 }
659 673
660 bool NaClProcessHost::StartWithLaunchedProcess() { 674 bool NaClProcessHost::StartWithLaunchedProcess() {
661 #if defined(OS_LINUX) 675 #if defined(OS_LINUX)
662 if (wait_for_nacl_gdb_) { 676 if (wait_for_nacl_gdb_) {
663 if (LaunchNaClGdb(base::GetProcId(process_->GetData().handle))) { 677 if (LaunchNaClGdb(base::GetProcId(process_->GetData().handle))) {
664 // We will be called with wait_for_nacl_gdb_ = false once debugger is 678 // We will be called with wait_for_nacl_gdb_ = false once debugger is
665 // attached to the program. 679 // attached to the program.
666 return true; 680 return true;
667 } 681 }
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
749 } else { 763 } else {
750 NaClStartDebugExceptionHandlerThread( 764 NaClStartDebugExceptionHandlerThread(
751 process_handle.Take(), info, 765 process_handle.Take(), info,
752 base::MessageLoopProxy::current(), 766 base::MessageLoopProxy::current(),
753 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker, 767 base::Bind(&NaClProcessHost::OnDebugExceptionHandlerLaunchedByBroker,
754 weak_factory_.GetWeakPtr())); 768 weak_factory_.GetWeakPtr()));
755 return true; 769 return true;
756 } 770 }
757 } 771 }
758 #endif 772 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698