OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "mojo/edk/system/node_controller.h" | 5 #include "mojo/edk/system/node_controller.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <limits> | 8 #include <limits> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
98 } // namespace | 98 } // namespace |
99 | 99 |
100 NodeController::PendingPortRequest::PendingPortRequest() {} | 100 NodeController::PendingPortRequest::PendingPortRequest() {} |
101 | 101 |
102 NodeController::PendingPortRequest::~PendingPortRequest() {} | 102 NodeController::PendingPortRequest::~PendingPortRequest() {} |
103 | 103 |
104 NodeController::ReservedPort::ReservedPort() {} | 104 NodeController::ReservedPort::ReservedPort() {} |
105 | 105 |
106 NodeController::ReservedPort::~ReservedPort() {} | 106 NodeController::ReservedPort::~ReservedPort() {} |
107 | 107 |
108 NodeController::PendingRemotePortConnection::PendingRemotePortConnection() {} | |
109 | |
110 NodeController::PendingRemotePortConnection::~PendingRemotePortConnection() {} | |
111 | |
112 NodeController::~NodeController() {} | 108 NodeController::~NodeController() {} |
113 | 109 |
114 NodeController::NodeController(Core* core) | 110 NodeController::NodeController(Core* core) |
115 : core_(core), | 111 : core_(core), |
116 name_(GetRandomNodeName()), | 112 name_(GetRandomNodeName()), |
117 node_(new ports::Node(name_, this)) { | 113 node_(new ports::Node(name_, this)) { |
118 DVLOG(1) << "Initializing node " << name_; | 114 DVLOG(1) << "Initializing node " << name_; |
119 } | 115 } |
120 | 116 |
121 void NodeController::SetIOTaskRunner( | 117 void NodeController::SetIOTaskRunner( |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
194 | 190 |
195 void NodeController::ConnectToParentPort(const ports::PortRef& local_port, | 191 void NodeController::ConnectToParentPort(const ports::PortRef& local_port, |
196 const std::string& token, | 192 const std::string& token, |
197 const base::Closure& callback) { | 193 const base::Closure& callback) { |
198 io_task_runner_->PostTask( | 194 io_task_runner_->PostTask( |
199 FROM_HERE, | 195 FROM_HERE, |
200 base::Bind(&NodeController::RequestParentPortConnectionOnIOThread, | 196 base::Bind(&NodeController::RequestParentPortConnectionOnIOThread, |
201 base::Unretained(this), local_port, token, callback)); | 197 base::Unretained(this), local_port, token, callback)); |
202 } | 198 } |
203 | 199 |
204 void NodeController::ConnectToRemotePort( | |
205 const ports::PortRef& local_port, | |
206 const ports::NodeName& remote_node_name, | |
207 const ports::PortName& remote_port_name, | |
208 const base::Closure& callback) { | |
209 if (remote_node_name == name_) { | |
210 // It's possible that two different code paths on the node are trying to | |
211 // bootstrap ports to each other (e.g. in Chrome single-process mode) | |
212 // without being aware of the fact. In this case we can initialize the port | |
213 // immediately (which can fail silently if it's already been initialized by | |
214 // the request on the other side), and invoke |callback|. | |
215 node_->InitializePort(local_port, name_, remote_port_name); | |
216 callback.Run(); | |
217 return; | |
218 } | |
219 | |
220 PendingRemotePortConnection connection; | |
221 connection.local_port = local_port; | |
222 connection.remote_node_name = remote_node_name; | |
223 connection.remote_port_name = remote_port_name; | |
224 connection.callback = callback; | |
225 io_task_runner_->PostTask( | |
226 FROM_HERE, | |
227 base::Bind(&NodeController::ConnectToRemotePortOnIOThread, | |
228 base::Unretained(this), connection)); | |
229 } | |
230 | |
231 void NodeController::RequestShutdown(const base::Closure& callback) { | 200 void NodeController::RequestShutdown(const base::Closure& callback) { |
232 { | 201 { |
233 base::AutoLock lock(shutdown_lock_); | 202 base::AutoLock lock(shutdown_lock_); |
234 shutdown_callback_ = callback; | 203 shutdown_callback_ = callback; |
235 } | 204 } |
236 | 205 |
237 AttemptShutdownIfRequested(); | 206 AttemptShutdownIfRequested(); |
238 } | 207 } |
239 | 208 |
240 void NodeController::ConnectToChildOnIOThread( | 209 void NodeController::ConnectToChildOnIOThread( |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
291 request.callback = callback; | 260 request.callback = callback; |
292 pending_port_requests_.push_back(request); | 261 pending_port_requests_.push_back(request); |
293 return; | 262 return; |
294 } | 263 } |
295 | 264 |
296 pending_parent_port_connections_.insert( | 265 pending_parent_port_connections_.insert( |
297 std::make_pair(local_port.name(), callback)); | 266 std::make_pair(local_port.name(), callback)); |
298 parent->RequestPortConnection(local_port.name(), token); | 267 parent->RequestPortConnection(local_port.name(), token); |
299 } | 268 } |
300 | 269 |
301 void NodeController::ConnectToRemotePortOnIOThread( | |
302 const PendingRemotePortConnection& connection) { | |
303 scoped_refptr<NodeChannel> peer = GetPeerChannel(connection.remote_node_name); | |
304 if (peer) { | |
305 // It's safe to initialize the port since we already have a channel to its | |
306 // peer. No need to actually send them a message. | |
307 int rv = node_->InitializePort(connection.local_port, | |
308 connection.remote_node_name, | |
309 connection.remote_port_name); | |
310 DCHECK_EQ(rv, ports::OK); | |
311 connection.callback.Run(); | |
312 return; | |
313 } | |
314 | |
315 // Save this for later. We'll initialize the port once this peer is added. | |
316 pending_remote_port_connections_[connection.remote_node_name].push_back( | |
317 connection); | |
318 } | |
319 | |
320 scoped_refptr<NodeChannel> NodeController::GetPeerChannel( | 270 scoped_refptr<NodeChannel> NodeController::GetPeerChannel( |
321 const ports::NodeName& name) { | 271 const ports::NodeName& name) { |
322 base::AutoLock lock(peers_lock_); | 272 base::AutoLock lock(peers_lock_); |
323 auto it = peers_.find(name); | 273 auto it = peers_.find(name); |
324 if (it == peers_.end()) | 274 if (it == peers_.end()) |
325 return nullptr; | 275 return nullptr; |
326 return it->second; | 276 return it->second; |
327 } | 277 } |
328 | 278 |
329 scoped_refptr<NodeChannel> NodeController::GetParentChannel() { | 279 scoped_refptr<NodeChannel> NodeController::GetParentChannel() { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
380 } | 330 } |
381 | 331 |
382 if (start_channel) | 332 if (start_channel) |
383 channel->Start(); | 333 channel->Start(); |
384 | 334 |
385 // Flush any queued message we need to deliver to this node. | 335 // Flush any queued message we need to deliver to this node. |
386 while (!pending_messages.empty()) { | 336 while (!pending_messages.empty()) { |
387 channel->PortsMessage(std::move(pending_messages.front())); | 337 channel->PortsMessage(std::move(pending_messages.front())); |
388 pending_messages.pop(); | 338 pending_messages.pop(); |
389 } | 339 } |
390 | |
391 // Complete any pending port connections to this peer. | |
392 auto connections_it = pending_remote_port_connections_.find(name); | |
393 if (connections_it != pending_remote_port_connections_.end()) { | |
394 for (const auto& connection : connections_it->second) { | |
395 int rv = node_->InitializePort(connection.local_port, | |
396 connection.remote_node_name, | |
397 connection.remote_port_name); | |
398 DCHECK_EQ(rv, ports::OK); | |
399 connection.callback.Run(); | |
400 } | |
401 pending_remote_port_connections_.erase(connections_it); | |
402 } | |
403 } | 340 } |
404 | 341 |
405 void NodeController::DropPeer(const ports::NodeName& name) { | 342 void NodeController::DropPeer(const ports::NodeName& name) { |
406 DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); | 343 DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); |
407 | 344 |
408 { | 345 { |
409 base::AutoLock lock(peers_lock_); | 346 base::AutoLock lock(peers_lock_); |
410 auto it = peers_.find(name); | 347 auto it = peers_.find(name); |
411 | 348 |
412 if (it != peers_.end()) { | 349 if (it != peers_.end()) { |
(...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
989 shutdown_callback_.Reset(); | 926 shutdown_callback_.Reset(); |
990 } | 927 } |
991 | 928 |
992 DCHECK(!callback.is_null()); | 929 DCHECK(!callback.is_null()); |
993 | 930 |
994 callback.Run(); | 931 callback.Run(); |
995 } | 932 } |
996 | 933 |
997 } // namespace edk | 934 } // namespace edk |
998 } // namespace mojo | 935 } // namespace mojo |
OLD | NEW |