| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/routed_raw_channel.h" | 5 #include "mojo/edk/system/routed_raw_channel.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "mojo/edk/embedder/embedder_internal.h" | 9 #include "mojo/edk/embedder/embedder_internal.h" |
| 10 #include "mojo/edk/system/message_pipe_dispatcher.h" | 10 #include "mojo/edk/system/message_pipe_dispatcher.h" |
| 11 | 11 |
| 12 namespace mojo { | 12 namespace mojo { |
| 13 namespace edk { | 13 namespace edk { |
| 14 | 14 |
| 15 namespace { | 15 namespace { |
| 16 const uint64_t kInternalRoutingId = 0; | 16 const uint64_t kInternalRoutingId = 0; |
| 17 | |
| 18 // These are messages sent over our internal routing id above, meant for the | |
| 19 // other side's RoutedRawChannel to dispatch. | |
| 20 enum InternalMessages { | |
| 21 ROUTE_CLOSED = 0, | |
| 22 }; | |
| 23 } | 17 } |
| 24 | 18 |
| 25 RoutedRawChannel::PendingMessage::PendingMessage() { | 19 RoutedRawChannel::PendingMessage::PendingMessage() { |
| 26 } | 20 } |
| 27 | 21 |
| 28 RoutedRawChannel::PendingMessage::~PendingMessage() { | 22 RoutedRawChannel::PendingMessage::~PendingMessage() { |
| 29 } | 23 } |
| 30 | 24 |
| 31 RoutedRawChannel::RoutedRawChannel( | 25 RoutedRawChannel::RoutedRawChannel( |
| 32 ScopedPlatformHandle handle, | 26 ScopedPlatformHandle handle, |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 70 CHECK_EQ(routes_[pipe_id], pipe); | 64 CHECK_EQ(routes_[pipe_id], pipe); |
| 71 routes_.erase(pipe_id); | 65 routes_.erase(pipe_id); |
| 72 | 66 |
| 73 // Only send a message to the other side to close the route if we hadn't | 67 // Only send a message to the other side to close the route if we hadn't |
| 74 // received a close route message. Otherwise they would keep going back and | 68 // received a close route message. Otherwise they would keep going back and |
| 75 // forth. | 69 // forth. |
| 76 if (close_routes_.find(pipe_id) != close_routes_.end()) { | 70 if (close_routes_.find(pipe_id) != close_routes_.end()) { |
| 77 close_routes_.erase(pipe_id); | 71 close_routes_.erase(pipe_id); |
| 78 } else if (channel_) { | 72 } else if (channel_) { |
| 79 // Default route id of 0 to reach the other side's RoutedRawChannel. | 73 // Default route id of 0 to reach the other side's RoutedRawChannel. |
| 80 char message_data[sizeof(char) + sizeof(uint64_t)]; | 74 char message_data[sizeof(uint64_t)]; |
| 81 message_data[0] = ROUTE_CLOSED; | 75 memcpy(&message_data[0], &pipe_id, sizeof(uint64_t)); |
| 82 memcpy(&message_data[1], &pipe_id, sizeof(uint64_t)); | |
| 83 scoped_ptr<MessageInTransit> message(new MessageInTransit( | 76 scoped_ptr<MessageInTransit> message(new MessageInTransit( |
| 84 MessageInTransit::Type::MESSAGE, arraysize(message_data), | 77 MessageInTransit::Type::MESSAGE, arraysize(message_data), |
| 85 message_data)); | 78 message_data)); |
| 86 message->set_route_id(kInternalRoutingId); | 79 message->set_route_id(kInternalRoutingId); |
| 87 channel_->WriteMessage(message.Pass()); | 80 channel_->WriteMessage(message.Pass()); |
| 88 } | 81 } |
| 89 | 82 |
| 90 if (!channel_ && routes_.empty()) { | 83 if (!channel_ && routes_.empty()) { |
| 91 // PostTask to avoid reentrancy since the broker might be calling us. | 84 // PostTask to avoid reentrancy since the broker might be calling us. |
| 92 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); | 85 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 103 DCHECK(internal::g_io_thread_task_runner->RunsTasksOnCurrentThread()); | 96 DCHECK(internal::g_io_thread_task_runner->RunsTasksOnCurrentThread()); |
| 104 // Note: normally, when a message arrives here we should find a corresponding | 97 // Note: normally, when a message arrives here we should find a corresponding |
| 105 // entry for the MessagePipeDispatcher with the given route_id. However it is | 98 // entry for the MessagePipeDispatcher with the given route_id. However it is |
| 106 // possible that they just connected, and due to race conditions one side has | 99 // possible that they just connected, and due to race conditions one side has |
| 107 // connected and sent a message (and even closed) before the other side had a | 100 // connected and sent a message (and even closed) before the other side had a |
| 108 // chance to register with this RoutedRawChannel. In that case, we must buffer | 101 // chance to register with this RoutedRawChannel. In that case, we must buffer |
| 109 // all messages. | 102 // all messages. |
| 110 base::AutoLock auto_lock(lock_); | 103 base::AutoLock auto_lock(lock_); |
| 111 uint64_t route_id = message_view.route_id(); | 104 uint64_t route_id = message_view.route_id(); |
| 112 if (route_id == kInternalRoutingId) { | 105 if (route_id == kInternalRoutingId) { |
| 113 if (message_view.num_bytes() != sizeof(char) + sizeof(uint64_t)) { | 106 if (message_view.num_bytes() != sizeof(uint64_t)) { |
| 114 NOTREACHED() << "Invalid internal message in RoutedRawChannel."; | 107 NOTREACHED() << "Invalid internal message in RoutedRawChannel." ; |
| 115 return; | 108 return; |
| 116 } | 109 } |
| 117 const char* bytes = static_cast<const char*>(message_view.bytes()); | 110 uint64_t closed_route = *static_cast<const uint64_t*>(message_view.bytes()); |
| 118 if (bytes[0] != ROUTE_CLOSED) { | |
| 119 NOTREACHED() << "Unknown internal message in RoutedRawChannel."; | |
| 120 return; | |
| 121 } | |
| 122 uint64_t closed_route = *reinterpret_cast<const uint64_t*>(&bytes[1]); | |
| 123 if (close_routes_.find(closed_route) != close_routes_.end()) { | 111 if (close_routes_.find(closed_route) != close_routes_.end()) { |
| 124 NOTREACHED() << "Should only receive one ROUTE_CLOSED per route."; | 112 NOTREACHED() << "Should only receive one ROUTE_CLOSED per route."; |
| 125 return; | 113 return; |
| 126 } | 114 } |
| 127 close_routes_.insert(closed_route); | 115 close_routes_.insert(closed_route); |
| 128 if (routes_.find(closed_route) == routes_.end()) | 116 if (routes_.find(closed_route) == routes_.end()) |
| 129 return; // This side hasn't connected yet. | 117 return; // This side hasn't connected yet. |
| 130 | 118 |
| 131 routes_[closed_route]->OnError(ERROR_READ_SHUTDOWN); | 119 routes_[closed_route]->OnError(ERROR_READ_SHUTDOWN); |
| 132 return; | 120 return; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 159 it->second->OnError(error); | 147 it->second->OnError(error); |
| 160 } | 148 } |
| 161 } | 149 } |
| 162 | 150 |
| 163 if (destruct) | 151 if (destruct) |
| 164 delete this; | 152 delete this; |
| 165 } | 153 } |
| 166 | 154 |
| 167 } // namespace edk | 155 } // namespace edk |
| 168 } // namespace mojo | 156 } // namespace mojo |
| OLD | NEW |