| 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/ports/node.h" | 5 #include "mojo/edk/system/ports/node.h" |
| 6 | 6 |
| 7 #include <string.h> | 7 #include <string.h> |
| 8 | 8 |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 57 Node::Node(const NodeName& name, NodeDelegate* delegate) | 57 Node::Node(const NodeName& name, NodeDelegate* delegate) |
| 58 : name_(name), | 58 : name_(name), |
| 59 delegate_(delegate) { | 59 delegate_(delegate) { |
| 60 } | 60 } |
| 61 | 61 |
| 62 Node::~Node() { | 62 Node::~Node() { |
| 63 if (!ports_.empty()) | 63 if (!ports_.empty()) |
| 64 DLOG(WARNING) << "Unclean shutdown for node " << name_; | 64 DLOG(WARNING) << "Unclean shutdown for node " << name_; |
| 65 } | 65 } |
| 66 | 66 |
| 67 bool Node::CanShutdownCleanly(bool allow_local_ports) { | 67 bool Node::CanShutdownCleanly(ShutdownPolicy policy) { |
| 68 base::AutoLock ports_lock(ports_lock_); | 68 base::AutoLock ports_lock(ports_lock_); |
| 69 | 69 |
| 70 if (!allow_local_ports) { | 70 if (policy == ShutdownPolicy::DONT_ALLOW_LOCAL_PORTS) { |
| 71 #if DCHECK_IS_ON() | 71 #if DCHECK_IS_ON() |
| 72 for (auto entry : ports_) { | 72 for (auto entry : ports_) { |
| 73 DVLOG(2) << "Port " << entry.first << " referencing node " | 73 DVLOG(2) << "Port " << entry.first << " referencing node " |
| 74 << entry.second->peer_node_name << " is blocking shutdown of " | 74 << entry.second->peer_node_name << " is blocking shutdown of " |
| 75 << "node " << name_ << " (state=" << entry.second->state << ")"; | 75 << "node " << name_ << " (state=" << entry.second->state << ")"; |
| 76 } | 76 } |
| 77 #endif | 77 #endif |
| 78 return ports_.empty(); | 78 return ports_.empty(); |
| 79 } | 79 } |
| 80 | 80 |
| 81 DCHECK_EQ(policy, ShutdownPolicy::ALLOW_LOCAL_PORTS); |
| 82 |
| 81 // NOTE: This is not efficient, though it probably doesn't need to be since | 83 // NOTE: This is not efficient, though it probably doesn't need to be since |
| 82 // relatively few ports should be open during shutdown and shutdown doesn't | 84 // relatively few ports should be open during shutdown and shutdown doesn't |
| 83 // need to be blazingly fast. | 85 // need to be blazingly fast. |
| 84 bool can_shutdown = true; | 86 bool can_shutdown = true; |
| 85 for (auto entry : ports_) { | 87 for (auto entry : ports_) { |
| 86 base::AutoLock lock(entry.second->lock); | 88 base::AutoLock lock(entry.second->lock); |
| 87 if (entry.second->peer_node_name != name_ && | 89 if (entry.second->peer_node_name != name_ && |
| 88 entry.second->state != Port::kReceiving) { | 90 entry.second->state != Port::kReceiving) { |
| 89 can_shutdown = false; | 91 can_shutdown = false; |
| 90 #if DCHECK_IS_ON() | 92 #if DCHECK_IS_ON() |
| (...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 524 DestroyAllPortsWithPeer(event.proxy_node_name, event.proxy_port_name); | 526 DestroyAllPortsWithPeer(event.proxy_node_name, event.proxy_port_name); |
| 525 return OK; | 527 return OK; |
| 526 } | 528 } |
| 527 | 529 |
| 528 // The port may have already been closed locally, in which case the | 530 // The port may have already been closed locally, in which case the |
| 529 // ObserveClosure message will contain the last_sequence_num field. | 531 // ObserveClosure message will contain the last_sequence_num field. |
| 530 // We can then silently ignore this message. | 532 // We can then silently ignore this message. |
| 531 scoped_refptr<Port> port = GetPort(port_name); | 533 scoped_refptr<Port> port = GetPort(port_name); |
| 532 if (!port) { | 534 if (!port) { |
| 533 DVLOG(1) << "ObserveProxy: " << port_name << "@" << name_ << " not found"; | 535 DVLOG(1) << "ObserveProxy: " << port_name << "@" << name_ << " not found"; |
| 534 | |
| 535 if (port_name != event.proxy_port_name && | |
| 536 port_name != event.proxy_to_port_name) { | |
| 537 // The receiving port may have been removed while this message was in | |
| 538 // transit. In this case, we restart the ObserveProxy circulation from | |
| 539 // the referenced proxy port to avoid leaking the proxy. | |
| 540 delegate_->ForwardMessage( | |
| 541 event.proxy_node_name, | |
| 542 NewInternalMessage( | |
| 543 event.proxy_port_name, EventType::kObserveProxy, event)); | |
| 544 } | |
| 545 return OK; | 536 return OK; |
| 546 } | 537 } |
| 547 | 538 |
| 548 DVLOG(2) << "ObserveProxy at " << port_name << "@" << name_ << ", proxy at " | 539 DVLOG(2) << "ObserveProxy at " << port_name << "@" << name_ << ", proxy at " |
| 549 << event.proxy_port_name << "@" | 540 << event.proxy_port_name << "@" |
| 550 << event.proxy_node_name << " pointing to " | 541 << event.proxy_node_name << " pointing to " |
| 551 << event.proxy_to_port_name << "@" | 542 << event.proxy_to_port_name << "@" |
| 552 << event.proxy_to_node_name; | 543 << event.proxy_to_node_name; |
| 553 | 544 |
| 554 { | 545 { |
| (...skipping 830 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1385 | 1376 |
| 1386 if (num_data_bytes) | 1377 if (num_data_bytes) |
| 1387 memcpy(header + 1, data, num_data_bytes); | 1378 memcpy(header + 1, data, num_data_bytes); |
| 1388 | 1379 |
| 1389 return message; | 1380 return message; |
| 1390 } | 1381 } |
| 1391 | 1382 |
| 1392 } // namespace ports | 1383 } // namespace ports |
| 1393 } // namespace edk | 1384 } // namespace edk |
| 1394 } // namespace mojo | 1385 } // namespace mojo |
| OLD | NEW |