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

Unified Diff: ipc/mojo/ipc_mojo_bootstrap.cc

Issue 553283002: IPC::ChannelMojo: Introduce IPC::MojoBootstrap for Windows (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed build error Created 6 years, 3 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 | « ipc/mojo/ipc_mojo_bootstrap.h ('k') | ipc/mojo/ipc_mojo_bootstrap_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ipc/mojo/ipc_mojo_bootstrap.cc
diff --git a/ipc/mojo/ipc_mojo_bootstrap.cc b/ipc/mojo/ipc_mojo_bootstrap.cc
new file mode 100644
index 0000000000000000000000000000000000000000..0082fb88dcac1a6118278ecf2d74c8737bd6975e
--- /dev/null
+++ b/ipc/mojo/ipc_mojo_bootstrap.cc
@@ -0,0 +1,205 @@
+// 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 "ipc/mojo/ipc_mojo_bootstrap.h"
+
+#include "base/logging.h"
+#include "base/process/process_handle.h"
+#include "ipc/ipc_message_utils.h"
+#include "ipc/ipc_platform_file.h"
+#include "mojo/embedder/platform_channel_pair.h"
+
+namespace IPC {
+
+namespace {
+
+// MojoBootstrap for the server process. You should create the instance
+// using MojoBootstrap::Create().
+class IPC_MOJO_EXPORT MojoServerBootstrap : public MojoBootstrap {
+ public:
+ MojoServerBootstrap();
+
+ virtual void OnClientLaunched(base::ProcessHandle process) OVERRIDE;
+
+ private:
+ void SendClientPipe();
+ void SendClientPipeIfReady();
+
+ // Listener implementations
+ virtual bool OnMessageReceived(const Message& message) OVERRIDE;
+ virtual void OnChannelConnected(int32 peer_pid) OVERRIDE;
+
+ mojo::embedder::ScopedPlatformHandle server_pipe_;
+ base::ProcessHandle client_process_;
+ bool connected_;
+
+ DISALLOW_COPY_AND_ASSIGN(MojoServerBootstrap);
+};
+
+MojoServerBootstrap::MojoServerBootstrap()
+ : client_process_(base::kNullProcessHandle), connected_(false) {
+}
+
+void MojoServerBootstrap::SendClientPipe() {
+ DCHECK_EQ(state(), STATE_INITIALIZED);
+ DCHECK_NE(client_process_, base::kNullProcessHandle);
+ DCHECK(connected_);
+
+ mojo::embedder::PlatformChannelPair channel_pair;
+ server_pipe_ = channel_pair.PassServerHandle();
+ PlatformFileForTransit client_pipe = GetFileHandleForProcess(
+#if defined(OS_POSIX)
+ channel_pair.PassClientHandle().release().fd,
+#else
+ channel_pair.PassClientHandle().release().handle,
+#endif
+ client_process_,
+ true);
+ CHECK(client_pipe != IPC::InvalidPlatformFileForTransit());
+ scoped_ptr<Message> message(new Message());
+ ParamTraits<PlatformFileForTransit>::Write(message.get(), client_pipe);
+ Send(message.release());
+
+ set_state(STATE_WAITING_ACK);
+}
+
+void MojoServerBootstrap::SendClientPipeIfReady() {
+ // Is the client launched?
+ if (client_process_ == base::kNullProcessHandle)
+ return;
+ // Has the bootstrap channel been made?
+ if (!connected_)
+ return;
+ SendClientPipe();
+}
+
+void MojoServerBootstrap::OnClientLaunched(base::ProcessHandle process) {
+ DCHECK_EQ(state(), STATE_INITIALIZED);
+ DCHECK_NE(process, base::kNullProcessHandle);
+ client_process_ = process;
+ SendClientPipeIfReady();
+}
+
+void MojoServerBootstrap::OnChannelConnected(int32 peer_pid) {
+ DCHECK_EQ(state(), STATE_INITIALIZED);
+ connected_ = true;
+ SendClientPipeIfReady();
+}
+
+bool MojoServerBootstrap::OnMessageReceived(const Message&) {
+ DCHECK_EQ(state(), STATE_WAITING_ACK);
+ set_state(STATE_READY);
+
+ delegate()->OnPipeAvailable(
+ mojo::embedder::ScopedPlatformHandle(server_pipe_.release()));
+
+ return true;
+}
+
+// MojoBootstrap for client processes. You should create the instance
+// using MojoBootstrap::Create().
+class IPC_MOJO_EXPORT MojoClientBootstrap : public MojoBootstrap {
+ public:
+ MojoClientBootstrap();
+
+ virtual void OnClientLaunched(base::ProcessHandle process) OVERRIDE;
+
+ private:
+ // Listener implementations
+ virtual bool OnMessageReceived(const Message& message) OVERRIDE;
+ virtual void OnChannelConnected(int32 peer_pid) OVERRIDE;
+
+ DISALLOW_COPY_AND_ASSIGN(MojoClientBootstrap);
+};
+
+MojoClientBootstrap::MojoClientBootstrap() {
+}
+
+bool MojoClientBootstrap::OnMessageReceived(const Message& message) {
+ PlatformFileForTransit pipe;
+ PickleIterator iter(message);
+ if (!ParamTraits<PlatformFileForTransit>::Read(&message, &iter, &pipe)) {
+ DLOG(WARNING) << "Failed to read a file handle from bootstrap channel.";
+ message.set_dispatch_error();
+ return false;
+ }
+
+ // Sends ACK back.
+ Send(new Message());
+ set_state(STATE_READY);
+ delegate()->OnPipeAvailable(
+ mojo::embedder::ScopedPlatformHandle(mojo::embedder::PlatformHandle(
+ PlatformFileForTransitToPlatformFile(pipe))));
+
+ return true;
+}
+
+void MojoClientBootstrap::OnClientLaunched(base::ProcessHandle process) {
+ // This notification should happen only on server processes.
+ NOTREACHED();
+}
+
+void MojoClientBootstrap::OnChannelConnected(int32 peer_pid) {
+}
+
+} // namespace
+
+// MojoBootstrap
+
+// static
+scoped_ptr<MojoBootstrap> MojoBootstrap::Create(ChannelHandle handle,
+ Channel::Mode mode,
+ Delegate* delegate) {
+ CHECK(mode == Channel::MODE_CLIENT || mode == Channel::MODE_SERVER);
+ scoped_ptr<MojoBootstrap> self =
+ mode == Channel::MODE_CLIENT
+ ? scoped_ptr<MojoBootstrap>(new MojoClientBootstrap())
+ : scoped_ptr<MojoBootstrap>(new MojoServerBootstrap());
+ scoped_ptr<Channel> bootstrap_channel =
+ Channel::Create(handle, mode, self.get());
+ self->Init(bootstrap_channel.Pass(), delegate);
+ return self.Pass();
+}
+
+MojoBootstrap::MojoBootstrap() : delegate_(NULL), state_(STATE_INITIALIZED) {
+}
+
+MojoBootstrap::~MojoBootstrap() {
+}
+
+void MojoBootstrap::Init(scoped_ptr<Channel> channel, Delegate* delegate) {
+ channel_ = channel.Pass();
+ delegate_ = delegate;
+}
+
+bool MojoBootstrap::Connect() {
+ return channel_->Connect();
+}
+
+void MojoBootstrap::OnBadMessageReceived(const Message& message) {
+ delegate_->OnBootstrapError();
+}
+
+void MojoBootstrap::OnChannelError() {
+ if (state_ == STATE_READY)
+ return;
+ DLOG(WARNING) << "Detected error on Mojo bootstrap channel.";
+ delegate()->OnBootstrapError();
+}
+
+bool MojoBootstrap::Send(Message* message) {
+ return channel_->Send(message);
+}
+
+#if defined(OS_POSIX) && !defined(OS_NACL)
+int MojoBootstrap::GetClientFileDescriptor() const {
+ return channel_->GetClientFileDescriptor();
+}
+
+int MojoBootstrap::TakeClientFileDescriptor() {
+ return channel_->TakeClientFileDescriptor();
+}
+#endif // defined(OS_POSIX) && !defined(OS_NACL)
+
+} // namespace IPC
« no previous file with comments | « ipc/mojo/ipc_mojo_bootstrap.h ('k') | ipc/mojo/ipc_mojo_bootstrap_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698