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

Unified Diff: mojo/shell/child_process.cc

Issue 1091513005: Separate mojo/shell into a runner and the application manager (shell) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: . Created 5 years, 8 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « mojo/shell/child_process.h ('k') | mojo/shell/child_process.mojom » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: mojo/shell/child_process.cc
diff --git a/mojo/shell/child_process.cc b/mojo/shell/child_process.cc
deleted file mode 100644
index df5eb498e565124c5346b36154dec395c83645d5..0000000000000000000000000000000000000000
--- a/mojo/shell/child_process.cc
+++ /dev/null
@@ -1,321 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "mojo/shell/child_process.h"
-
-#include "base/base_switches.h"
-#include "base/bind.h"
-#include "base/callback_helpers.h"
-#include "base/command_line.h"
-#include "base/debug/debugger.h"
-#include "base/files/file_path.h"
-#include "base/location.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/message_loop/message_loop.h"
-#include "base/single_thread_task_runner.h"
-#include "base/synchronization/waitable_event.h"
-#include "base/threading/thread.h"
-#include "base/threading/thread_checker.h"
-#include "mojo/common/message_pump_mojo.h"
-#include "mojo/edk/embedder/embedder.h"
-#include "mojo/edk/embedder/platform_channel_pair.h"
-#include "mojo/edk/embedder/process_delegate.h"
-#include "mojo/edk/embedder/scoped_platform_handle.h"
-#include "mojo/edk/embedder/simple_platform_support.h"
-#include "mojo/public/cpp/system/core.h"
-#include "mojo/shell/child_process.mojom.h"
-#include "mojo/shell/native_application_support.h"
-#include "mojo/shell/switches.h"
-
-namespace mojo {
-namespace shell {
-
-namespace {
-
-// Blocker ---------------------------------------------------------------------
-
-// Blocks a thread until another thread unblocks it, at which point it unblocks
-// and runs a closure provided by that thread.
-class Blocker {
- public:
- class Unblocker {
- public:
- explicit Unblocker(Blocker* blocker = nullptr) : blocker_(blocker) {}
- ~Unblocker() {}
-
- void Unblock(base::Closure run_after) {
- DCHECK(blocker_);
- DCHECK(blocker_->run_after_.is_null());
- blocker_->run_after_ = run_after;
- blocker_->event_.Signal();
- blocker_ = nullptr;
- }
-
- private:
- Blocker* blocker_;
-
- // Copy and assign allowed.
- };
-
- Blocker() : event_(true, false) {}
- ~Blocker() {}
-
- void Block() {
- DCHECK(run_after_.is_null());
- event_.Wait();
- run_after_.Run();
- }
-
- Unblocker GetUnblocker() { return Unblocker(this); }
-
- private:
- base::WaitableEvent event_;
- base::Closure run_after_;
-
- DISALLOW_COPY_AND_ASSIGN(Blocker);
-};
-
-// AppContext ------------------------------------------------------------------
-
-class ChildControllerImpl;
-
-// Should be created and initialized on the main thread.
-class AppContext : public embedder::ProcessDelegate {
- public:
- AppContext()
- : io_thread_("io_thread"), controller_thread_("controller_thread") {}
- ~AppContext() override {}
-
- void Init() {
- // Initialize Mojo before starting any threads.
- embedder::Init(make_scoped_ptr(new embedder::SimplePlatformSupport()));
-
- // Create and start our I/O thread.
- base::Thread::Options io_thread_options(base::MessageLoop::TYPE_IO, 0);
- CHECK(io_thread_.StartWithOptions(io_thread_options));
- io_runner_ = io_thread_.message_loop_proxy().get();
- CHECK(io_runner_.get());
-
- // Create and start our controller thread.
- base::Thread::Options controller_thread_options;
- controller_thread_options.message_loop_type =
- base::MessageLoop::TYPE_CUSTOM;
- controller_thread_options.message_pump_factory =
- base::Bind(&common::MessagePumpMojo::Create);
- CHECK(controller_thread_.StartWithOptions(controller_thread_options));
- controller_runner_ = controller_thread_.message_loop_proxy().get();
- CHECK(controller_runner_.get());
-
- // TODO(vtl): This should be SLAVE, not NONE.
- embedder::InitIPCSupport(embedder::ProcessType::NONE, controller_runner_,
- this, io_runner_,
- embedder::ScopedPlatformHandle());
- }
-
- void Shutdown() {
- Blocker blocker;
- shutdown_unblocker_ = blocker.GetUnblocker();
- controller_runner_->PostTask(
- FROM_HERE, base::Bind(&AppContext::ShutdownOnControllerThread,
- base::Unretained(this)));
- blocker.Block();
- }
-
- base::SingleThreadTaskRunner* io_runner() const { return io_runner_.get(); }
-
- base::SingleThreadTaskRunner* controller_runner() const {
- return controller_runner_.get();
- }
-
- ChildControllerImpl* controller() const { return controller_.get(); }
-
- void set_controller(scoped_ptr<ChildControllerImpl> controller) {
- controller_ = controller.Pass();
- }
-
- private:
- void ShutdownOnControllerThread() {
- // First, destroy the controller.
- controller_.reset();
-
- // Next shutdown IPC. We'll unblock the main thread in OnShutdownComplete().
- embedder::ShutdownIPCSupport();
- }
-
- // ProcessDelegate implementation.
- void OnShutdownComplete() override {
- shutdown_unblocker_.Unblock(base::Closure());
- }
-
- base::Thread io_thread_;
- scoped_refptr<base::SingleThreadTaskRunner> io_runner_;
-
- base::Thread controller_thread_;
- scoped_refptr<base::SingleThreadTaskRunner> controller_runner_;
-
- // Accessed only on the controller thread.
- scoped_ptr<ChildControllerImpl> controller_;
-
- // Used to unblock the main thread on shutdown.
- Blocker::Unblocker shutdown_unblocker_;
-
- DISALLOW_COPY_AND_ASSIGN(AppContext);
-};
-
-// ChildControllerImpl ------------------------------------------------------
-
-class ChildControllerImpl : public ChildController, public ErrorHandler {
- public:
- ~ChildControllerImpl() override {
- DCHECK(thread_checker_.CalledOnValidThread());
-
- // TODO(vtl): Pass in the result from |MainMain()|.
- on_app_complete_.Run(MOJO_RESULT_UNIMPLEMENTED);
- }
-
- // To be executed on the controller thread. Creates the |ChildController|,
- // etc.
- static void Init(AppContext* app_context,
- embedder::ScopedPlatformHandle platform_channel,
- const Blocker::Unblocker& unblocker) {
- DCHECK(app_context);
- DCHECK(platform_channel.is_valid());
-
- DCHECK(!app_context->controller());
-
- scoped_ptr<ChildControllerImpl> impl(
- new ChildControllerImpl(app_context, unblocker));
-
- ScopedMessagePipeHandle host_message_pipe(embedder::CreateChannel(
- platform_channel.Pass(), app_context->io_runner(),
- base::Bind(&ChildControllerImpl::DidCreateChannel,
- base::Unretained(impl.get())),
- base::MessageLoopProxy::current()));
-
- impl->Bind(host_message_pipe.Pass());
-
- app_context->set_controller(impl.Pass());
- }
-
- void Bind(ScopedMessagePipeHandle handle) { binding_.Bind(handle.Pass()); }
-
- // |ErrorHandler| methods:
- void OnConnectionError() override {
- // A connection error means the connection to the shell is lost. This is not
- // recoverable.
- LOG(ERROR) << "Connection error to the shell.";
- _exit(1);
- }
-
- // |ChildController| methods:
- void StartApp(const String& app_path,
- bool clean_app_path,
- InterfaceRequest<Application> application_request,
- const StartAppCallback& on_app_complete) override {
- DVLOG(2) << "ChildControllerImpl::StartApp(" << app_path << ", ...)";
- DCHECK(thread_checker_.CalledOnValidThread());
-
- on_app_complete_ = on_app_complete;
- unblocker_.Unblock(base::Bind(&ChildControllerImpl::StartAppOnMainThread,
- base::FilePath::FromUTF8Unsafe(app_path),
- clean_app_path
- ? NativeApplicationCleanup::DELETE
- : NativeApplicationCleanup::DONT_DELETE,
- base::Passed(&application_request)));
- }
-
- void ExitNow(int32_t exit_code) override {
- DVLOG(2) << "ChildControllerImpl::ExitNow(" << exit_code << ")";
- _exit(exit_code);
- }
-
- private:
- ChildControllerImpl(AppContext* app_context,
- const Blocker::Unblocker& unblocker)
- : app_context_(app_context),
- unblocker_(unblocker),
- channel_info_(nullptr),
- binding_(this) {
- binding_.set_error_handler(this);
- }
-
- // Callback for |embedder::CreateChannel()|.
- void DidCreateChannel(embedder::ChannelInfo* channel_info) {
- DVLOG(2) << "ChildControllerImpl::DidCreateChannel()";
- DCHECK(thread_checker_.CalledOnValidThread());
- channel_info_ = channel_info;
- }
-
- static void StartAppOnMainThread(
- const base::FilePath& app_path,
- NativeApplicationCleanup cleanup,
- InterfaceRequest<Application> application_request) {
- // TODO(vtl): This is copied from in_process_native_runner.cc.
- DVLOG(2) << "Loading/running Mojo app from " << app_path.value()
- << " out of process";
-
- // We intentionally don't unload the native library as its lifetime is the
- // same as that of the process.
- base::NativeLibrary app_library = LoadNativeApplication(app_path, cleanup);
- RunNativeApplication(app_library, application_request.Pass());
- }
-
- base::ThreadChecker thread_checker_;
- AppContext* const app_context_;
- Blocker::Unblocker unblocker_;
- StartAppCallback on_app_complete_;
-
- embedder::ChannelInfo* channel_info_;
- Binding<ChildController> binding_;
-
- DISALLOW_COPY_AND_ASSIGN(ChildControllerImpl);
-};
-
-} // namespace
-
-int ChildProcessMain() {
- DVLOG(2) << "ChildProcessMain()";
- const base::CommandLine& command_line =
- *base::CommandLine::ForCurrentProcess();
- if (command_line.HasSwitch(switches::kWaitForDebugger)) {
- std::string app = command_line.GetSwitchValueASCII(switches::kApp);
-#if defined(OS_WIN)
- MessageBox(NULL, command_line.GetSwitchValueNative(switches::kApp).c_str(),
- command_line.GetSwitchValueNative(switches::kApp).c_str(),
- MB_OK | MB_SETFOREGROUND);
-#else
- LOG(ERROR) << command_line.GetSwitchValueASCII(switches::kApp)
- << " waiting for GDB. pid: " << getpid();
- base::debug::WaitForDebugger(60, true);
-#endif
- }
-
- embedder::ScopedPlatformHandle platform_channel =
- embedder::PlatformChannelPair::PassClientHandleFromParentProcess(
- command_line);
- CHECK(platform_channel.is_valid());
-
- DCHECK(!base::MessageLoop::current());
-
- AppContext app_context;
- app_context.Init();
-
- Blocker blocker;
- app_context.controller_runner()->PostTask(
- FROM_HERE,
- base::Bind(&ChildControllerImpl::Init, base::Unretained(&app_context),
- base::Passed(&platform_channel), blocker.GetUnblocker()));
- // This will block, then run whatever the controller wants.
- blocker.Block();
-
- app_context.Shutdown();
-
- return 0;
-}
-
-} // namespace shell
-} // namespace mojo
« no previous file with comments | « mojo/shell/child_process.h ('k') | mojo/shell/child_process.mojom » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698