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

Unified Diff: mojo/edk/system/remote_message_pipe_bootstrap.cc

Issue 1585493002: [mojo] Ports EDK (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 11 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
Index: mojo/edk/system/remote_message_pipe_bootstrap.cc
diff --git a/mojo/edk/system/remote_message_pipe_bootstrap.cc b/mojo/edk/system/remote_message_pipe_bootstrap.cc
new file mode 100644
index 0000000000000000000000000000000000000000..4d46437dd8b403a16f93e963e54c3c851d370481
--- /dev/null
+++ b/mojo/edk/system/remote_message_pipe_bootstrap.cc
@@ -0,0 +1,189 @@
+// Copyright 2016 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/edk/system/remote_message_pipe_bootstrap.h"
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/macros.h"
+#include "base/thread_task_runner_handle.h"
+#include "mojo/edk/embedder/embedder.h"
+#include "mojo/edk/system/node_controller.h"
+
+namespace mojo {
+namespace edk {
+
+namespace {
+
+const size_t kMaxTokenSize = 256;
+
+class ParentBootstrap : public RemoteMessagePipeBootstrap {
+ public:
+ static void Create(NodeController* node_controller,
+ ScopedPlatformHandle platform_handle,
+ const std::string& token) {
+ // Owns itself.
+ new ParentBootstrap(node_controller, std::move(platform_handle), token);
+ }
+
+ private:
+ ParentBootstrap(NodeController* node_controller,
+ ScopedPlatformHandle platform_handle,
+ const std::string& token)
+ : RemoteMessagePipeBootstrap(std::move(platform_handle)),
+ node_controller_(node_controller),
+ token_(token) {
+ DCHECK_LE(token_.size(), kMaxTokenSize);
+ Channel::MessagePtr message(new Channel::Message(token_.size(), 0));
+ memcpy(message->mutable_payload(), token_.data(), token_.size());
+ channel_->Write(std::move(message));
+ }
+
+ ~ParentBootstrap() override {}
+
+ void OnTokenReceived(const std::string& token) override {
+ // It's possible for two different endpoints in the same parent process to
+ // initiate parent bootstrap on the same platform channel without being
+ // aware of the other.
+ //
+ // This will successfully connect the two endpoints as long as at least one
+ // of the ParentBootstrap instances receives the other's token. It's OK that
+ // they race. NodeController will silently ignore any missed reservations.
+ node_controller_->ConnectReservedPorts(token_, token);
+ ShutDown();
+ }
+
+ NodeController* node_controller_;
+ const std::string token_;
+
+ DISALLOW_COPY_AND_ASSIGN(ParentBootstrap);
+};
+
+class ChildBootstrap : public RemoteMessagePipeBootstrap {
+ public:
+ static void Create(NodeController* node_controller,
+ ScopedPlatformHandle platform_handle,
+ const ports::PortRef& port,
+ const base::Closure& callback) {
+ // Owns itself.
+ new ChildBootstrap(
+ node_controller, std::move(platform_handle), port, callback);
+ }
+
+ private:
+ ChildBootstrap(NodeController* node_controller,
+ ScopedPlatformHandle platform_handle,
+ const ports::PortRef& port,
+ const base::Closure& callback)
+ : RemoteMessagePipeBootstrap(std::move(platform_handle)),
+ node_controller_(node_controller),
+ port_(port),
+ callback_(callback) {
+ }
+
+ ~ChildBootstrap() override {}
+
+ void OnTokenReceived(const std::string& token) override {
+ CHECK(!callback_.is_null());
+ base::Closure callback = callback_;
+ callback_.Reset();
+
+ node_controller_->ConnectToParentPort(port_, token, callback);
+ ShutDown();
+ }
+
+ NodeController* const node_controller_;
+ const ports::PortRef port_;
+ base::Closure callback_;
+
+ DISALLOW_COPY_AND_ASSIGN(ChildBootstrap);
+};
+
+} // namespace
+
+// static
+void RemoteMessagePipeBootstrap::CreateForParent(
+ NodeController* node_controller,
+ ScopedPlatformHandle platform_handle,
+ const std::string& token) {
+ node_controller->io_task_runner()->PostTask(
+ FROM_HERE,
+ base::Bind(&ParentBootstrap::Create, base::Unretained(node_controller),
+ base::Passed(&platform_handle), token));
+}
+
+// static
+void RemoteMessagePipeBootstrap::CreateForChild(
+ NodeController* node_controller,
+ ScopedPlatformHandle platform_handle,
+ const ports::PortRef& port,
+ const base::Closure& callback) {
+ node_controller->io_task_runner()->PostTask(
+ FROM_HERE,
+ base::Bind(&ChildBootstrap::Create, base::Unretained(node_controller),
+ base::Passed(&platform_handle), port, callback));
+}
+
+RemoteMessagePipeBootstrap::~RemoteMessagePipeBootstrap() {
+ DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
+ base::MessageLoop::current()->RemoveDestructionObserver(this);
+ if (channel_)
+ channel_->ShutDown();
+}
+
+RemoteMessagePipeBootstrap::RemoteMessagePipeBootstrap(
+ ScopedPlatformHandle platform_handle)
+ : io_task_runner_(base::ThreadTaskRunnerHandle::Get()),
+ channel_(Channel::Create(this, std::move(platform_handle),
+ io_task_runner_)) {
+ base::MessageLoop::current()->AddDestructionObserver(this);
+ channel_->Start();
+}
+
+void RemoteMessagePipeBootstrap::ShutDown() {
+ DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
+
+ if (shutting_down_)
+ return;
+
+ shutting_down_ = true;
+
+ // Shut down asynchronously so implementations are free to call it whenever.
+ io_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&RemoteMessagePipeBootstrap::ShutDownNow,
+ base::Unretained(this)));
+}
+
+void RemoteMessagePipeBootstrap::WillDestroyCurrentMessageLoop() {
+ DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
+ ShutDownNow();
+}
+
+void RemoteMessagePipeBootstrap::OnChannelMessage(
+ const void* payload,
+ size_t payload_size,
+ ScopedPlatformHandleVectorPtr handles) {
+ DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
+ DCHECK(!handles || !handles->size());
+ if (payload_size > kMaxTokenSize) {
+ DLOG(ERROR) << "Invalid token payload. Dropping message pipe bootstrap.";
+ ShutDown();
+ return;
+ }
+
+ OnTokenReceived(std::string(static_cast<const char*>(payload), payload_size));
+}
+
+void RemoteMessagePipeBootstrap::OnChannelError() {
+ DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
+ ShutDown();
+}
+
+void RemoteMessagePipeBootstrap::ShutDownNow() {
+ delete this;
+}
+
+} // namespace edk
+} // namespace mojo

Powered by Google App Engine
This is Rietveld 408576698