summaryrefslogtreecommitdiffstats
path: root/mojo/shell
diff options
context:
space:
mode:
authorviettrungluu@chromium.org <viettrungluu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-20 05:59:58 +0000
committerviettrungluu@chromium.org <viettrungluu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-20 05:59:58 +0000
commitd7dc6add17de8faa9c74a4500100ee8c70afce8a (patch)
treeddd1990d07b4716512a1d1b7d7336ccb170f00d3 /mojo/shell
parent6b0384ace0bffaff9ad364907544405c9d03e06a (diff)
downloadchromium_src-d7dc6add17de8faa9c74a4500100ee8c70afce8a.zip
chromium_src-d7dc6add17de8faa9c74a4500100ee8c70afce8a.tar.gz
chromium_src-d7dc6add17de8faa9c74a4500100ee8c70afce8a.tar.bz2
Mojo: Create channels on both sides of AppChildProcess(Host).
R=sky@chromium.org Review URL: https://codereview.chromium.org/199553003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@258212 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'mojo/shell')
-rw-r--r--mojo/shell/app_child_process.cc164
-rw-r--r--mojo/shell/app_child_process_host.cc29
-rw-r--r--mojo/shell/app_child_process_host.h10
-rw-r--r--mojo/shell/child_process.cc4
-rw-r--r--mojo/shell/child_process.h12
-rw-r--r--mojo/shell/desktop/mojo_main.cc15
-rw-r--r--mojo/shell/test_child_process.cc12
7 files changed, 206 insertions, 40 deletions
diff --git a/mojo/shell/app_child_process.cc b/mojo/shell/app_child_process.cc
index ea2f3f7..0105aca 100644
--- a/mojo/shell/app_child_process.cc
+++ b/mojo/shell/app_child_process.cc
@@ -4,11 +4,154 @@
#include "mojo/shell/app_child_process.h"
+#include "base/bind.h"
+#include "base/location.h"
#include "base/logging.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/message_loop/message_loop.h"
+#include "base/single_thread_task_runner.h"
+#include "base/threading/thread.h"
+#include "base/threading/thread_checker.h"
+#include "mojo/common/message_pump_mojo.h"
+#include "mojo/embedder/embedder.h"
+#include "mojo/public/system/core_cpp.h"
namespace mojo {
namespace shell {
+namespace {
+
+class AppChildControllerImpl;
+
+// AppContext ------------------------------------------------------------------
+
+// Should be created and initialized on the main thread.
+class AppContext {
+ public:
+ AppContext()
+ : io_thread_("io_thread"),
+ controller_thread_("controller_thread") {}
+ ~AppContext() {}
+
+ void Init() {
+ // Initialize Mojo before starting any threads.
+ embedder::Init();
+
+ // 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_);
+
+ // 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_);
+ }
+
+ base::SingleThreadTaskRunner* io_runner() const {
+ return io_runner_.get();
+ }
+
+ base::SingleThreadTaskRunner* controller_runner() const {
+ return controller_runner_.get();
+ }
+
+ AppChildControllerImpl* controller() const {
+ return controller_.get();
+ }
+
+ void set_controller(scoped_ptr<AppChildControllerImpl> controller) {
+ controller_ = controller.Pass();
+ }
+
+ private:
+ 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<AppChildControllerImpl> controller_;
+
+ DISALLOW_COPY_AND_ASSIGN(AppContext);
+};
+
+// AppChildControllerImpl ------------------------------------------------------
+
+// TODO(vtl): This will inherit from an |AppChildController| interface.
+class AppChildControllerImpl {
+ public:
+ ~AppChildControllerImpl() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ }
+
+ // To be executed on the controller thread. Creates the |AppChildController|,
+ // etc.
+ static void Init(
+ AppContext* app_context,
+ embedder::ScopedPlatformHandle platform_channel,
+ scoped_refptr<base::SingleThreadTaskRunner> main_thread_runner) {
+ DCHECK(app_context);
+ DCHECK(platform_channel.is_valid());
+ DCHECK(main_thread_runner);
+
+ DCHECK(!app_context->controller());
+ app_context->set_controller(
+ make_scoped_ptr(new AppChildControllerImpl(app_context)));
+ app_context->controller()->CreateChannel(platform_channel.Pass(),
+ main_thread_runner);
+ }
+
+ private:
+ AppChildControllerImpl(AppContext* app_context)
+ : app_context_(app_context),
+ channel_info_(NULL) {
+ }
+
+ void CreateChannel(
+ embedder::ScopedPlatformHandle platform_channel,
+ scoped_refptr<base::SingleThreadTaskRunner> main_thread_runner) {
+ DVLOG(2) << "AppChildControllerImpl::CreateChannel()";
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ ScopedMessagePipeHandle host_message_pipe(embedder::CreateChannel(
+ platform_channel.Pass(),
+ app_context_->io_runner(),
+ base::Bind(&AppChildControllerImpl::DidCreateChannel,
+ base::Unretained(this), main_thread_runner),
+ base::MessageLoopProxy::current()));
+
+ // TODO(vtl): Set up RemotePtr here.
+ }
+
+ // Callback for |embedder::CreateChannel()|.
+ void DidCreateChannel(
+ scoped_refptr<base::SingleThreadTaskRunner> main_thread_runner,
+ embedder::ChannelInfo* channel_info) {
+ DVLOG(2) << "AppChildControllerImpl::DidCreateChannel()";
+ DCHECK(thread_checker_.CalledOnValidThread());
+ channel_info_ = channel_info;
+ }
+
+ base::ThreadChecker thread_checker_;
+ AppContext* const app_context_;
+ embedder::ChannelInfo* channel_info_;
+
+ DISALLOW_COPY_AND_ASSIGN(AppChildControllerImpl);
+};
+
+} // namespace
+
+// AppChildProcess -------------------------------------------------------------
+
AppChildProcess::AppChildProcess() {
}
@@ -16,11 +159,26 @@ AppChildProcess::~AppChildProcess() {
}
void AppChildProcess::Main() {
- VLOG(2) << "AppChildProcess::Main()";
+ DVLOG(2) << "AppChildProcess::Main()";
+
+ AppContext app_context;
+ app_context.Init();
+
+ {
+ base::MessageLoop message_loop;
- // TODO(vtl)
+ app_context.controller_runner()->PostTask(
+ FROM_HERE,
+ base::Bind(&AppChildControllerImpl::Init,
+ base::Unretained(&app_context),
+ base::Passed(platform_channel()),
+ scoped_refptr<base::SingleThreadTaskRunner>(
+ message_loop.message_loop_proxy())));
- platform_channel()->reset();
+ // Eventually, we'll get a task posted telling us to quit this message loop,
+ // which will also tell us what to do afterwards (e.g., run |MojoMain()|).
+ message_loop.Run();
+ }
}
} // namespace shell
diff --git a/mojo/shell/app_child_process_host.cc b/mojo/shell/app_child_process_host.cc
index 288b1aa..9f14532 100644
--- a/mojo/shell/app_child_process_host.cc
+++ b/mojo/shell/app_child_process_host.cc
@@ -4,25 +4,50 @@
#include "mojo/shell/app_child_process_host.h"
+#include "base/message_loop/message_loop.h"
+#include "mojo/embedder/embedder.h"
+#include "mojo/public/system/core_cpp.h"
+#include "mojo/shell/context.h"
+#include "mojo/shell/task_runners.h"
+
namespace mojo {
namespace shell {
AppChildProcessHost::AppChildProcessHost(Context* context,
AppDelegate* app_delegate)
: ChildProcessHost(context, this, ChildProcess::TYPE_APP),
- app_delegate_(app_delegate) {
+ app_delegate_(app_delegate),
+ channel_info_(NULL) {
}
AppChildProcessHost::~AppChildProcessHost() {
}
void AppChildProcessHost::DidStart(bool success) {
+ DVLOG(2) << "AppChildProcessHost::DidStart()";
+
if (!success) {
app_delegate_->DidTerminate();
return;
}
- // TODO(vtl): What else?
+ mojo::ScopedMessagePipeHandle child_message_pipe(embedder::CreateChannel(
+ platform_channel()->Pass(),
+ context()->task_runners()->io_runner(),
+ base::Bind(&AppChildProcessHost::DidCreateChannel,
+ base::Unretained(this)),
+ base::MessageLoop::current()->message_loop_proxy()));
+
+ // TODO(vtl): Hook up a RemotePtr, etc.
+}
+
+// Callback for |embedder::CreateChannel()|.
+void AppChildProcessHost::DidCreateChannel(
+ embedder::ChannelInfo* channel_info) {
+ DVLOG(2) << "AppChildProcessHost::DidCreateChannel()";
+
+ CHECK(channel_info);
+ channel_info_ = channel_info;
}
} // namespace shell
diff --git a/mojo/shell/app_child_process_host.h b/mojo/shell/app_child_process_host.h
index 0ce5330..2ddd276 100644
--- a/mojo/shell/app_child_process_host.h
+++ b/mojo/shell/app_child_process_host.h
@@ -9,6 +9,11 @@
#include "mojo/shell/child_process_host.h"
namespace mojo {
+
+namespace embedder {
+struct ChannelInfo;
+}
+
namespace shell {
// Note: After |Start()|, this object must remain alive until the delegate's
@@ -28,8 +33,13 @@ class AppChildProcessHost : public ChildProcessHost,
// |ChildProcessHost::Delegate| method:
virtual void DidStart(bool success) OVERRIDE;
+ // Callback for |embedder::CreateChannel()|.
+ void DidCreateChannel(embedder::ChannelInfo* channel_info);
+
AppDelegate* const app_delegate_;
+ embedder::ChannelInfo* channel_info_;
+
DISALLOW_COPY_AND_ASSIGN(AppChildProcessHost);
};
diff --git a/mojo/shell/child_process.cc b/mojo/shell/child_process.cc
index fa195bb..01e3a0c 100644
--- a/mojo/shell/child_process.cc
+++ b/mojo/shell/child_process.cc
@@ -50,10 +50,6 @@ scoped_ptr<ChildProcess> ChildProcess::Create(const CommandLine& command_line) {
return rv.Pass();
}
-void ChildProcess::Run() {
- Main();
-}
-
ChildProcess::ChildProcess() {
}
diff --git a/mojo/shell/child_process.h b/mojo/shell/child_process.h
index 2a0fd48..8e4d4c6 100644
--- a/mojo/shell/child_process.h
+++ b/mojo/shell/child_process.h
@@ -27,17 +27,15 @@ class ChildProcess {
TYPE_APP
};
+ virtual ~ChildProcess();
+
// Returns null if the command line doesn't indicate that this is a child
// process. |main()| should call this, and if it returns non-null it should
- // call |Run()| inside a main message loop.
+ // call |Main()| (without a message loop on the current thread).
static scoped_ptr<ChildProcess> Create(const base::CommandLine& command_line);
- void Run();
-
- virtual ~ChildProcess();
-
// To be implemented by subclasses. This is the "entrypoint" for a child
- // process.
+ // process. Run with no message loop for the main thread.
virtual void Main() = 0;
protected:
@@ -48,7 +46,7 @@ class ChildProcess {
}
private:
- // Available in |Main()| (after |Run()|).
+ // Available in |Main()| (after a successful |Create()|).
embedder::ScopedPlatformHandle platform_channel_;
DISALLOW_COPY_AND_ASSIGN(ChildProcess);
diff --git a/mojo/shell/desktop/mojo_main.cc b/mojo/shell/desktop/mojo_main.cc
index dec73f4f..42b94a2 100644
--- a/mojo/shell/desktop/mojo_main.cc
+++ b/mojo/shell/desktop/mojo_main.cc
@@ -7,8 +7,7 @@
#include "base/logging.h"
#include "base/macros.h" // TODO(vtl): Remove.
#include "base/message_loop/message_loop.h"
-#include "mojo/common/message_pump_mojo.h"
-#include "mojo/embedder/embedder.h"
+#include "mojo/common/message_pump_mojo.h" // TODO(vtl): Remove.
#include "mojo/shell/child_process.h"
#include "mojo/shell/child_process_host.h" // TODO(vtl): Remove.
#include "mojo/shell/context.h"
@@ -58,17 +57,7 @@ int main(int argc, char** argv) {
if (scoped_ptr<mojo::shell::ChildProcess> child_process =
mojo::shell::ChildProcess::Create(
*CommandLine::ForCurrentProcess())) {
- // TODO(vtl): Consider making a |Context| for child processes, and
- // initializing stuff there.
- mojo::embedder::Init();
- base::MessageLoop message_loop(
- scoped_ptr<base::MessagePump>(new mojo::common::MessagePumpMojo()));
- message_loop.PostTask(
- FROM_HERE,
- base::Bind(&mojo::shell::ChildProcess::Run,
- base::Unretained(child_process.get())));
-
- message_loop.Run();
+ child_process->Main();
} else {
gfx::GLSurface::InitializeOneOff();
diff --git a/mojo/shell/test_child_process.cc b/mojo/shell/test_child_process.cc
index ce55b83..fe187a5 100644
--- a/mojo/shell/test_child_process.cc
+++ b/mojo/shell/test_child_process.cc
@@ -12,14 +12,6 @@
namespace mojo {
namespace shell {
-namespace {
-
-void TrivialPostedTask() {
- VLOG(2) << "TrivialPostedTask()";
-}
-
-} // namespace
-
TestChildProcess::TestChildProcess() {
}
@@ -29,9 +21,7 @@ TestChildProcess::~TestChildProcess() {
void TestChildProcess::Main() {
VLOG(2) << "TestChildProcess::Main()";
- base::MessageLoop::current()->PostTask(FROM_HERE,
- base::Bind(&TrivialPostedTask));
- base::MessageLoop::current()->QuitWhenIdle();
+ CHECK(!base::MessageLoop::current());
}
} // namespace shell