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 |