| 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 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 97 } // namespace | 97 } // namespace |
| 98 | 98 |
| 99 NodeController::PendingPortRequest::PendingPortRequest() {} | 99 NodeController::PendingPortRequest::PendingPortRequest() {} |
| 100 | 100 |
| 101 NodeController::PendingPortRequest::~PendingPortRequest() {} | 101 NodeController::PendingPortRequest::~PendingPortRequest() {} |
| 102 | 102 |
| 103 NodeController::ReservedPort::ReservedPort() {} | 103 NodeController::ReservedPort::ReservedPort() {} |
| 104 | 104 |
| 105 NodeController::ReservedPort::~ReservedPort() {} | 105 NodeController::ReservedPort::~ReservedPort() {} |
| 106 | 106 |
| 107 NodeController::PendingRemotePortConnection::PendingRemotePortConnection() {} | |
| 108 | |
| 109 NodeController::PendingRemotePortConnection::~PendingRemotePortConnection() {} | |
| 110 | |
| 111 NodeController::~NodeController() {} | 107 NodeController::~NodeController() {} |
| 112 | 108 |
| 113 NodeController::NodeController(Core* core) | 109 NodeController::NodeController(Core* core) |
| 114 : core_(core), | 110 : core_(core), |
| 115 name_(GetRandomNodeName()), | 111 name_(GetRandomNodeName()), |
| 116 node_(new ports::Node(name_, this)) { | 112 node_(new ports::Node(name_, this)) { |
| 117 DVLOG(1) << "Initializing node " << name_; | 113 DVLOG(1) << "Initializing node " << name_; |
| 118 } | 114 } |
| 119 | 115 |
| 120 void NodeController::SetIOTaskRunner( | 116 void NodeController::SetIOTaskRunner( |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 193 | 189 |
| 194 void NodeController::ConnectToParentPort(const ports::PortRef& local_port, | 190 void NodeController::ConnectToParentPort(const ports::PortRef& local_port, |
| 195 const std::string& token, | 191 const std::string& token, |
| 196 const base::Closure& callback) { | 192 const base::Closure& callback) { |
| 197 io_task_runner_->PostTask( | 193 io_task_runner_->PostTask( |
| 198 FROM_HERE, | 194 FROM_HERE, |
| 199 base::Bind(&NodeController::RequestParentPortConnectionOnIOThread, | 195 base::Bind(&NodeController::RequestParentPortConnectionOnIOThread, |
| 200 base::Unretained(this), local_port, token, callback)); | 196 base::Unretained(this), local_port, token, callback)); |
| 201 } | 197 } |
| 202 | 198 |
| 203 void NodeController::ConnectToRemotePort( | |
| 204 const ports::PortRef& local_port, | |
| 205 const ports::NodeName& remote_node_name, | |
| 206 const ports::PortName& remote_port_name, | |
| 207 const base::Closure& callback) { | |
| 208 if (remote_node_name == name_) { | |
| 209 // It's possible that two different code paths on the node are trying to | |
| 210 // bootstrap ports to each other (e.g. in Chrome single-process mode) | |
| 211 // without being aware of the fact. In this case we can initialize the port | |
| 212 // immediately (which can fail silently if it's already been initialized by | |
| 213 // the request on the other side), and invoke |callback|. | |
| 214 node_->InitializePort(local_port, name_, remote_port_name); | |
| 215 callback.Run(); | |
| 216 return; | |
| 217 } | |
| 218 | |
| 219 PendingRemotePortConnection connection; | |
| 220 connection.local_port = local_port; | |
| 221 connection.remote_node_name = remote_node_name; | |
| 222 connection.remote_port_name = remote_port_name; | |
| 223 connection.callback = callback; | |
| 224 io_task_runner_->PostTask( | |
| 225 FROM_HERE, | |
| 226 base::Bind(&NodeController::ConnectToRemotePortOnIOThread, | |
| 227 base::Unretained(this), connection)); | |
| 228 } | |
| 229 | |
| 230 void NodeController::RequestShutdown(const base::Closure& callback) { | 199 void NodeController::RequestShutdown(const base::Closure& callback) { |
| 231 { | 200 { |
| 232 base::AutoLock lock(shutdown_lock_); | 201 base::AutoLock lock(shutdown_lock_); |
| 233 shutdown_callback_ = callback; | 202 shutdown_callback_ = callback; |
| 234 } | 203 } |
| 235 | 204 |
| 236 AttemptShutdownIfRequested(); | 205 AttemptShutdownIfRequested(); |
| 237 } | 206 } |
| 238 | 207 |
| 239 void NodeController::ConnectToChildOnIOThread( | 208 void NodeController::ConnectToChildOnIOThread( |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 286 request.callback = callback; | 255 request.callback = callback; |
| 287 pending_port_requests_.push_back(request); | 256 pending_port_requests_.push_back(request); |
| 288 return; | 257 return; |
| 289 } | 258 } |
| 290 | 259 |
| 291 pending_parent_port_connections_.insert( | 260 pending_parent_port_connections_.insert( |
| 292 std::make_pair(local_port.name(), callback)); | 261 std::make_pair(local_port.name(), callback)); |
| 293 parent->RequestPortConnection(local_port.name(), token); | 262 parent->RequestPortConnection(local_port.name(), token); |
| 294 } | 263 } |
| 295 | 264 |
| 296 void NodeController::ConnectToRemotePortOnIOThread( | |
| 297 const PendingRemotePortConnection& connection) { | |
| 298 scoped_refptr<NodeChannel> peer = GetPeerChannel(connection.remote_node_name); | |
| 299 if (peer) { | |
| 300 // It's safe to initialize the port since we already have a channel to its | |
| 301 // peer. No need to actually send them a message. | |
| 302 int rv = node_->InitializePort(connection.local_port, | |
| 303 connection.remote_node_name, | |
| 304 connection.remote_port_name); | |
| 305 DCHECK_EQ(rv, ports::OK); | |
| 306 connection.callback.Run(); | |
| 307 return; | |
| 308 } | |
| 309 | |
| 310 // Save this for later. We'll initialize the port once this:: peer is added. | |
| 311 pending_remote_port_connections_[connection.remote_node_name].push_back( | |
| 312 connection); | |
| 313 } | |
| 314 | |
| 315 scoped_refptr<NodeChannel> NodeController::GetPeerChannel( | 265 scoped_refptr<NodeChannel> NodeController::GetPeerChannel( |
| 316 const ports::NodeName& name) { | 266 const ports::NodeName& name) { |
| 317 base::AutoLock lock(peers_lock_); | 267 base::AutoLock lock(peers_lock_); |
| 318 auto it = peers_.find(name); | 268 auto it = peers_.find(name); |
| 319 if (it == peers_.end()) | 269 if (it == peers_.end()) |
| 320 return nullptr; | 270 return nullptr; |
| 321 return it->second; | 271 return it->second; |
| 322 } | 272 } |
| 323 | 273 |
| 324 scoped_refptr<NodeChannel> NodeController::GetParentChannel() { | 274 scoped_refptr<NodeChannel> NodeController::GetParentChannel() { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 368 if (start_channel) | 318 if (start_channel) |
| 369 channel->Start(); | 319 channel->Start(); |
| 370 | 320 |
| 371 // Flush any queued message we need to deliver to this node. | 321 // Flush any queued message we need to deliver to this node. |
| 372 while (!pending_messages.empty()) { | 322 while (!pending_messages.empty()) { |
| 373 ports::ScopedMessage message = std::move(pending_messages.front()); | 323 ports::ScopedMessage message = std::move(pending_messages.front()); |
| 374 channel->PortsMessage( | 324 channel->PortsMessage( |
| 375 static_cast<PortsMessage*>(message.get())->TakeChannelMessage()); | 325 static_cast<PortsMessage*>(message.get())->TakeChannelMessage()); |
| 376 pending_messages.pop(); | 326 pending_messages.pop(); |
| 377 } | 327 } |
| 378 | |
| 379 // Complete any pending port connections to this peer. | |
| 380 auto connections_it = pending_remote_port_connections_.find(name); | |
| 381 if (connections_it != pending_remote_port_connections_.end()) { | |
| 382 for (const auto& connection : connections_it->second) { | |
| 383 int rv = node_->InitializePort(connection.local_port, | |
| 384 connection.remote_node_name, | |
| 385 connection.remote_port_name); | |
| 386 DCHECK_EQ(rv, ports::OK); | |
| 387 connection.callback.Run(); | |
| 388 } | |
| 389 pending_remote_port_connections_.erase(connections_it); | |
| 390 } | |
| 391 } | 328 } |
| 392 | 329 |
| 393 void NodeController::DropPeer(const ports::NodeName& name) { | 330 void NodeController::DropPeer(const ports::NodeName& name) { |
| 394 DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); | 331 DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); |
| 395 | 332 |
| 396 { | 333 { |
| 397 base::AutoLock lock(peers_lock_); | 334 base::AutoLock lock(peers_lock_); |
| 398 auto it = peers_.find(name); | 335 auto it = peers_.find(name); |
| 399 | 336 |
| 400 if (it != peers_.end()) { | 337 if (it != peers_.end()) { |
| (...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 840 shutdown_callback_.Reset(); | 777 shutdown_callback_.Reset(); |
| 841 } | 778 } |
| 842 | 779 |
| 843 DCHECK(!callback.is_null()); | 780 DCHECK(!callback.is_null()); |
| 844 | 781 |
| 845 callback.Run(); | 782 callback.Run(); |
| 846 } | 783 } |
| 847 | 784 |
| 848 } // namespace edk | 785 } // namespace edk |
| 849 } // namespace mojo | 786 } // namespace mojo |
| OLD | NEW |