| 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 |