| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/channel_endpoint.h" | 5 #include "mojo/edk/system/channel_endpoint.h" |
| 6 | 6 |
| 7 #include <utility> |
| 8 |
| 7 #include "base/logging.h" | 9 #include "base/logging.h" |
| 8 #include "base/threading/platform_thread.h" | 10 #include "base/threading/platform_thread.h" |
| 9 #include "mojo/edk/system/channel.h" | 11 #include "mojo/edk/system/channel.h" |
| 10 #include "mojo/edk/system/channel_endpoint_client.h" | 12 #include "mojo/edk/system/channel_endpoint_client.h" |
| 11 #include "mojo/public/cpp/system/macros.h" | 13 #include "mojo/public/cpp/system/macros.h" |
| 12 | 14 |
| 13 namespace mojo { | 15 namespace mojo { |
| 14 namespace system { | 16 namespace system { |
| 15 | 17 |
| 16 ChannelEndpoint::ChannelEndpoint(ChannelEndpointClient* client, | 18 ChannelEndpoint::ChannelEndpoint(ChannelEndpointClient* client, |
| 17 unsigned client_port, | 19 unsigned client_port, |
| 18 MessageInTransitQueue* message_queue) | 20 MessageInTransitQueue* message_queue) |
| 19 : state_(State::PAUSED), | 21 : state_(State::PAUSED), |
| 20 client_(client), | 22 client_(client), |
| 21 client_port_(client_port), | 23 client_port_(client_port), |
| 22 channel_(nullptr) { | 24 channel_(nullptr) { |
| 23 DCHECK(client_ || message_queue); | 25 DCHECK(client_ || message_queue); |
| 24 | 26 |
| 25 if (message_queue) | 27 if (message_queue) |
| 26 channel_message_queue_.Swap(message_queue); | 28 channel_message_queue_.Swap(message_queue); |
| 27 } | 29 } |
| 28 | 30 |
| 29 bool ChannelEndpoint::EnqueueMessage(scoped_ptr<MessageInTransit> message) { | 31 bool ChannelEndpoint::EnqueueMessage( |
| 32 std::unique_ptr<MessageInTransit> message) { |
| 30 DCHECK(message); | 33 DCHECK(message); |
| 31 | 34 |
| 32 MutexLocker locker(&mutex_); | 35 MutexLocker locker(&mutex_); |
| 33 | 36 |
| 34 switch (state_) { | 37 switch (state_) { |
| 35 case State::PAUSED: | 38 case State::PAUSED: |
| 36 channel_message_queue_.AddMessage(message.Pass()); | 39 channel_message_queue_.AddMessage(std::move(message)); |
| 37 return true; | 40 return true; |
| 38 case State::RUNNING: | 41 case State::RUNNING: |
| 39 return WriteMessageNoLock(message.Pass()); | 42 return WriteMessageNoLock(std::move(message)); |
| 40 case State::DEAD: | 43 case State::DEAD: |
| 41 return false; | 44 return false; |
| 42 } | 45 } |
| 43 | 46 |
| 44 NOTREACHED(); | 47 NOTREACHED(); |
| 45 return false; | 48 return false; |
| 46 } | 49 } |
| 47 | 50 |
| 48 bool ChannelEndpoint::ReplaceClient(ChannelEndpointClient* client, | 51 bool ChannelEndpoint::ReplaceClient(ChannelEndpointClient* client, |
| 49 unsigned client_port) { | 52 unsigned client_port) { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 89 bool ok = WriteMessageNoLock(channel_message_queue_.GetMessage()); | 92 bool ok = WriteMessageNoLock(channel_message_queue_.GetMessage()); |
| 90 LOG_IF(WARNING, !ok) << "Failed to write enqueue message to channel"; | 93 LOG_IF(WARNING, !ok) << "Failed to write enqueue message to channel"; |
| 91 } | 94 } |
| 92 | 95 |
| 93 if (!client_) { | 96 if (!client_) { |
| 94 channel_->DetachEndpoint(this, local_id_, remote_id_); | 97 channel_->DetachEndpoint(this, local_id_, remote_id_); |
| 95 DieNoLock(); | 98 DieNoLock(); |
| 96 } | 99 } |
| 97 } | 100 } |
| 98 | 101 |
| 99 void ChannelEndpoint::OnReadMessage(scoped_ptr<MessageInTransit> message) { | 102 void ChannelEndpoint::OnReadMessage(std::unique_ptr<MessageInTransit> message) { |
| 100 if (message->type() == MessageInTransit::Type::ENDPOINT_CLIENT) { | 103 if (message->type() == MessageInTransit::Type::ENDPOINT_CLIENT) { |
| 101 OnReadMessageForClient(message.Pass()); | 104 OnReadMessageForClient(std::move(message)); |
| 102 return; | 105 return; |
| 103 } | 106 } |
| 104 | 107 |
| 105 DCHECK_EQ(message->type(), MessageInTransit::Type::ENDPOINT); | 108 DCHECK_EQ(message->type(), MessageInTransit::Type::ENDPOINT); |
| 106 | 109 |
| 107 // TODO(vtl) | 110 // TODO(vtl) |
| 108 // Note that this won't crash on Release builds, which is important (since the | 111 // Note that this won't crash on Release builds, which is important (since the |
| 109 // other side may be malicious). Doing nothing is safe and will dispose of the | 112 // other side may be malicious). Doing nothing is safe and will dispose of the |
| 110 // message. | 113 // message. |
| 111 NOTREACHED(); | 114 NOTREACHED(); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 141 client->OnDetachFromChannel(client_port); | 144 client->OnDetachFromChannel(client_port); |
| 142 } | 145 } |
| 143 | 146 |
| 144 ChannelEndpoint::~ChannelEndpoint() { | 147 ChannelEndpoint::~ChannelEndpoint() { |
| 145 DCHECK(!client_); | 148 DCHECK(!client_); |
| 146 DCHECK(!channel_); | 149 DCHECK(!channel_); |
| 147 DCHECK(!local_id_.is_valid()); | 150 DCHECK(!local_id_.is_valid()); |
| 148 DCHECK(!remote_id_.is_valid()); | 151 DCHECK(!remote_id_.is_valid()); |
| 149 } | 152 } |
| 150 | 153 |
| 151 bool ChannelEndpoint::WriteMessageNoLock(scoped_ptr<MessageInTransit> message) { | 154 bool ChannelEndpoint::WriteMessageNoLock( |
| 155 std::unique_ptr<MessageInTransit> message) { |
| 152 DCHECK(message); | 156 DCHECK(message); |
| 153 | 157 |
| 154 mutex_.AssertHeld(); | 158 mutex_.AssertHeld(); |
| 155 | 159 |
| 156 DCHECK(channel_); | 160 DCHECK(channel_); |
| 157 DCHECK(local_id_.is_valid()); | 161 DCHECK(local_id_.is_valid()); |
| 158 DCHECK(remote_id_.is_valid()); | 162 DCHECK(remote_id_.is_valid()); |
| 159 | 163 |
| 160 message->SerializeAndCloseDispatchers(channel_); | 164 message->SerializeAndCloseDispatchers(channel_); |
| 161 message->set_source_id(local_id_); | 165 message->set_source_id(local_id_); |
| 162 message->set_destination_id(remote_id_); | 166 message->set_destination_id(remote_id_); |
| 163 return channel_->WriteMessage(message.Pass()); | 167 return channel_->WriteMessage(std::move(message)); |
| 164 } | 168 } |
| 165 | 169 |
| 166 void ChannelEndpoint::OnReadMessageForClient( | 170 void ChannelEndpoint::OnReadMessageForClient( |
| 167 scoped_ptr<MessageInTransit> message) { | 171 std::unique_ptr<MessageInTransit> message) { |
| 168 DCHECK_EQ(message->type(), MessageInTransit::Type::ENDPOINT_CLIENT); | 172 DCHECK_EQ(message->type(), MessageInTransit::Type::ENDPOINT_CLIENT); |
| 169 | 173 |
| 170 scoped_refptr<ChannelEndpointClient> client; | 174 scoped_refptr<ChannelEndpointClient> client; |
| 171 unsigned client_port = 0; | 175 unsigned client_port = 0; |
| 172 | 176 |
| 173 // This loop is to make |ReplaceClient()| work. We can't call the client's | 177 // This loop is to make |ReplaceClient()| work. We can't call the client's |
| 174 // |OnReadMessage()| under our lock, so by the time we do that, |client| may | 178 // |OnReadMessage()| under our lock, so by the time we do that, |client| may |
| 175 // no longer be our client. | 179 // no longer be our client. |
| 176 // | 180 // |
| 177 // In that case, |client| must return false. We'll then yield, and retry with | 181 // In that case, |client| must return false. We'll then yield, and retry with |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 215 DCHECK(remote_id_.is_valid()); | 219 DCHECK(remote_id_.is_valid()); |
| 216 | 220 |
| 217 state_ = State::DEAD; | 221 state_ = State::DEAD; |
| 218 channel_ = nullptr; | 222 channel_ = nullptr; |
| 219 local_id_ = ChannelEndpointId(); | 223 local_id_ = ChannelEndpointId(); |
| 220 remote_id_ = ChannelEndpointId(); | 224 remote_id_ = ChannelEndpointId(); |
| 221 } | 225 } |
| 222 | 226 |
| 223 } // namespace system | 227 } // namespace system |
| 224 } // namespace mojo | 228 } // namespace mojo |
| OLD | NEW |