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

Side by Side 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "mojo/edk/system/remote_message_pipe_bootstrap.h"
6
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/macros.h"
10 #include "base/thread_task_runner_handle.h"
11 #include "mojo/edk/embedder/embedder.h"
12 #include "mojo/edk/system/node_controller.h"
13
14 namespace mojo {
15 namespace edk {
16
17 namespace {
18
19 const size_t kMaxTokenSize = 256;
20
21 class ParentBootstrap : public RemoteMessagePipeBootstrap {
22 public:
23 static void Create(NodeController* node_controller,
24 ScopedPlatformHandle platform_handle,
25 const std::string& token) {
26 // Owns itself.
27 new ParentBootstrap(node_controller, std::move(platform_handle), token);
28 }
29
30 private:
31 ParentBootstrap(NodeController* node_controller,
32 ScopedPlatformHandle platform_handle,
33 const std::string& token)
34 : RemoteMessagePipeBootstrap(std::move(platform_handle)),
35 node_controller_(node_controller),
36 token_(token) {
37 DCHECK_LE(token_.size(), kMaxTokenSize);
38 Channel::MessagePtr message(new Channel::Message(token_.size(), 0));
39 memcpy(message->mutable_payload(), token_.data(), token_.size());
40 channel_->Write(std::move(message));
41 }
42
43 ~ParentBootstrap() override {}
44
45 void OnTokenReceived(const std::string& token) override {
46 // It's possible for two different endpoints in the same parent process to
47 // initiate parent bootstrap on the same platform channel without being
48 // aware of the other.
49 //
50 // This will successfully connect the two endpoints as long as at least one
51 // of the ParentBootstrap instances receives the other's token. It's OK that
52 // they race. NodeController will silently ignore any missed reservations.
53 node_controller_->ConnectReservedPorts(token_, token);
54 ShutDown();
55 }
56
57 NodeController* node_controller_;
58 const std::string token_;
59
60 DISALLOW_COPY_AND_ASSIGN(ParentBootstrap);
61 };
62
63 class ChildBootstrap : public RemoteMessagePipeBootstrap {
64 public:
65 static void Create(NodeController* node_controller,
66 ScopedPlatformHandle platform_handle,
67 const ports::PortRef& port,
68 const base::Closure& callback) {
69 // Owns itself.
70 new ChildBootstrap(
71 node_controller, std::move(platform_handle), port, callback);
72 }
73
74 private:
75 ChildBootstrap(NodeController* node_controller,
76 ScopedPlatformHandle platform_handle,
77 const ports::PortRef& port,
78 const base::Closure& callback)
79 : RemoteMessagePipeBootstrap(std::move(platform_handle)),
80 node_controller_(node_controller),
81 port_(port),
82 callback_(callback) {
83 }
84
85 ~ChildBootstrap() override {}
86
87 void OnTokenReceived(const std::string& token) override {
88 CHECK(!callback_.is_null());
89 base::Closure callback = callback_;
90 callback_.Reset();
91
92 node_controller_->ConnectToParentPort(port_, token, callback);
93 ShutDown();
94 }
95
96 NodeController* const node_controller_;
97 const ports::PortRef port_;
98 base::Closure callback_;
99
100 DISALLOW_COPY_AND_ASSIGN(ChildBootstrap);
101 };
102
103 } // namespace
104
105 // static
106 void RemoteMessagePipeBootstrap::CreateForParent(
107 NodeController* node_controller,
108 ScopedPlatformHandle platform_handle,
109 const std::string& token) {
110 node_controller->io_task_runner()->PostTask(
111 FROM_HERE,
112 base::Bind(&ParentBootstrap::Create, base::Unretained(node_controller),
113 base::Passed(&platform_handle), token));
114 }
115
116 // static
117 void RemoteMessagePipeBootstrap::CreateForChild(
118 NodeController* node_controller,
119 ScopedPlatformHandle platform_handle,
120 const ports::PortRef& port,
121 const base::Closure& callback) {
122 node_controller->io_task_runner()->PostTask(
123 FROM_HERE,
124 base::Bind(&ChildBootstrap::Create, base::Unretained(node_controller),
125 base::Passed(&platform_handle), port, callback));
126 }
127
128 RemoteMessagePipeBootstrap::~RemoteMessagePipeBootstrap() {
129 DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
130 base::MessageLoop::current()->RemoveDestructionObserver(this);
131 if (channel_)
132 channel_->ShutDown();
133 }
134
135 RemoteMessagePipeBootstrap::RemoteMessagePipeBootstrap(
136 ScopedPlatformHandle platform_handle)
137 : io_task_runner_(base::ThreadTaskRunnerHandle::Get()),
138 channel_(Channel::Create(this, std::move(platform_handle),
139 io_task_runner_)) {
140 base::MessageLoop::current()->AddDestructionObserver(this);
141 channel_->Start();
142 }
143
144 void RemoteMessagePipeBootstrap::ShutDown() {
145 DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
146
147 if (shutting_down_)
148 return;
149
150 shutting_down_ = true;
151
152 // Shut down asynchronously so implementations are free to call it whenever.
153 io_task_runner_->PostTask(
154 FROM_HERE,
155 base::Bind(&RemoteMessagePipeBootstrap::ShutDownNow,
156 base::Unretained(this)));
157 }
158
159 void RemoteMessagePipeBootstrap::WillDestroyCurrentMessageLoop() {
160 DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
161 ShutDownNow();
162 }
163
164 void RemoteMessagePipeBootstrap::OnChannelMessage(
165 const void* payload,
166 size_t payload_size,
167 ScopedPlatformHandleVectorPtr handles) {
168 DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
169 DCHECK(!handles || !handles->size());
170 if (payload_size > kMaxTokenSize) {
171 DLOG(ERROR) << "Invalid token payload. Dropping message pipe bootstrap.";
172 ShutDown();
173 return;
174 }
175
176 OnTokenReceived(std::string(static_cast<const char*>(payload), payload_size));
177 }
178
179 void RemoteMessagePipeBootstrap::OnChannelError() {
180 DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
181 ShutDown();
182 }
183
184 void RemoteMessagePipeBootstrap::ShutDownNow() {
185 delete this;
186 }
187
188 } // namespace edk
189 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698