| 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/slave_connection_manager.h" | 5 #include "mojo/edk/system/slave_connection_manager.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
| 11 #include "base/location.h" | 11 #include "base/location.h" |
| 12 #include "base/logging.h" | 12 #include "base/logging.h" |
| 13 #include "base/message_loop/message_loop.h" | 13 #include "base/message_loop/message_loop.h" |
| 14 #include "mojo/edk/system/connection_manager_messages.h" | 14 #include "mojo/edk/system/connection_manager_messages.h" |
| 15 #include "mojo/edk/system/message_in_transit.h" | 15 #include "mojo/edk/system/message_in_transit.h" |
| 16 #include "mojo/edk/util/make_unique.h" | 16 #include "mojo/edk/util/make_unique.h" |
| 17 | 17 |
| 18 using mojo::embedder::ScopedPlatformHandle; |
| 18 using mojo::platform::TaskRunner; | 19 using mojo::platform::TaskRunner; |
| 19 using mojo::util::MutexLocker; | 20 using mojo::util::MutexLocker; |
| 20 using mojo::util::RefPtr; | 21 using mojo::util::RefPtr; |
| 21 | 22 |
| 22 namespace mojo { | 23 namespace mojo { |
| 23 namespace system { | 24 namespace system { |
| 24 | 25 |
| 25 // SlaveConnectionManager ------------------------------------------------------ | 26 // SlaveConnectionManager ------------------------------------------------------ |
| 26 | 27 |
| 27 SlaveConnectionManager::SlaveConnectionManager( | 28 SlaveConnectionManager::SlaveConnectionManager( |
| (...skipping 14 matching lines...) Expand all Loading... |
| 42 DCHECK_EQ(awaiting_ack_type_, NOT_AWAITING_ACK); | 43 DCHECK_EQ(awaiting_ack_type_, NOT_AWAITING_ACK); |
| 43 DCHECK(!ack_result_); | 44 DCHECK(!ack_result_); |
| 44 DCHECK(!ack_peer_process_identifier_); | 45 DCHECK(!ack_peer_process_identifier_); |
| 45 DCHECK(!ack_is_first_); | 46 DCHECK(!ack_is_first_); |
| 46 DCHECK(!ack_platform_handle_); | 47 DCHECK(!ack_platform_handle_); |
| 47 } | 48 } |
| 48 | 49 |
| 49 void SlaveConnectionManager::Init( | 50 void SlaveConnectionManager::Init( |
| 50 RefPtr<TaskRunner>&& delegate_thread_task_runner, | 51 RefPtr<TaskRunner>&& delegate_thread_task_runner, |
| 51 embedder::SlaveProcessDelegate* slave_process_delegate, | 52 embedder::SlaveProcessDelegate* slave_process_delegate, |
| 52 embedder::ScopedPlatformHandle platform_handle) { | 53 ScopedPlatformHandle platform_handle) { |
| 53 DCHECK(delegate_thread_task_runner); | 54 DCHECK(delegate_thread_task_runner); |
| 54 DCHECK(slave_process_delegate); | 55 DCHECK(slave_process_delegate); |
| 55 DCHECK(platform_handle.is_valid()); | 56 DCHECK(platform_handle.is_valid()); |
| 56 DCHECK(!delegate_thread_task_runner_); | 57 DCHECK(!delegate_thread_task_runner_); |
| 57 DCHECK(!slave_process_delegate_); | 58 DCHECK(!slave_process_delegate_); |
| 58 DCHECK(!private_thread_.message_loop()); | 59 DCHECK(!private_thread_.message_loop()); |
| 59 | 60 |
| 60 delegate_thread_task_runner_ = std::move(delegate_thread_task_runner); | 61 delegate_thread_task_runner_ = std::move(delegate_thread_task_runner); |
| 61 slave_process_delegate_ = slave_process_delegate; | 62 slave_process_delegate_ = slave_process_delegate; |
| 62 CHECK(private_thread_.StartWithOptions( | 63 CHECK(private_thread_.StartWithOptions( |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 109 base::Unretained(this), connection_id, &result)); | 110 base::Unretained(this), connection_id, &result)); |
| 110 event_.Wait(); | 111 event_.Wait(); |
| 111 DCHECK(result == Result::FAILURE || result == Result::SUCCESS); | 112 DCHECK(result == Result::FAILURE || result == Result::SUCCESS); |
| 112 return result == Result::SUCCESS; | 113 return result == Result::SUCCESS; |
| 113 } | 114 } |
| 114 | 115 |
| 115 ConnectionManager::Result SlaveConnectionManager::Connect( | 116 ConnectionManager::Result SlaveConnectionManager::Connect( |
| 116 const ConnectionIdentifier& connection_id, | 117 const ConnectionIdentifier& connection_id, |
| 117 ProcessIdentifier* peer_process_identifier, | 118 ProcessIdentifier* peer_process_identifier, |
| 118 bool* is_first, | 119 bool* is_first, |
| 119 embedder::ScopedPlatformHandle* platform_handle) { | 120 ScopedPlatformHandle* platform_handle) { |
| 120 AssertNotOnPrivateThread(); | 121 AssertNotOnPrivateThread(); |
| 121 DCHECK(peer_process_identifier); | 122 DCHECK(peer_process_identifier); |
| 122 DCHECK(is_first); | 123 DCHECK(is_first); |
| 123 DCHECK(platform_handle); | 124 DCHECK(platform_handle); |
| 124 DCHECK(!platform_handle->is_valid()); // Not technically wrong, but unlikely. | 125 DCHECK(!platform_handle->is_valid()); // Not technically wrong, but unlikely. |
| 125 | 126 |
| 126 MutexLocker locker(&mutex_); | 127 MutexLocker locker(&mutex_); |
| 127 Result result = Result::FAILURE; | 128 Result result = Result::FAILURE; |
| 128 private_thread_.message_loop()->PostTask( | 129 private_thread_.message_loop()->PostTask( |
| 129 FROM_HERE, | 130 FROM_HERE, |
| 130 base::Bind(&SlaveConnectionManager::ConnectOnPrivateThread, | 131 base::Bind(&SlaveConnectionManager::ConnectOnPrivateThread, |
| 131 base::Unretained(this), connection_id, &result, | 132 base::Unretained(this), connection_id, &result, |
| 132 peer_process_identifier, is_first, platform_handle)); | 133 peer_process_identifier, is_first, platform_handle)); |
| 133 event_.Wait(); | 134 event_.Wait(); |
| 134 return result; | 135 return result; |
| 135 } | 136 } |
| 136 | 137 |
| 137 void SlaveConnectionManager::InitOnPrivateThread( | 138 void SlaveConnectionManager::InitOnPrivateThread( |
| 138 embedder::ScopedPlatformHandle platform_handle) { | 139 ScopedPlatformHandle platform_handle) { |
| 139 AssertOnPrivateThread(); | 140 AssertOnPrivateThread(); |
| 140 | 141 |
| 141 raw_channel_ = RawChannel::Create(platform_handle.Pass()); | 142 raw_channel_ = RawChannel::Create(platform_handle.Pass()); |
| 142 raw_channel_->Init(this); | 143 raw_channel_->Init(this); |
| 143 event_.Signal(); | 144 event_.Signal(); |
| 144 } | 145 } |
| 145 | 146 |
| 146 void SlaveConnectionManager::ShutdownOnPrivateThread() { | 147 void SlaveConnectionManager::ShutdownOnPrivateThread() { |
| 147 AssertOnPrivateThread(); | 148 AssertOnPrivateThread(); |
| 148 | 149 |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 201 } | 202 } |
| 202 awaiting_ack_type_ = AWAITING_CANCEL_CONNECT_ACK; | 203 awaiting_ack_type_ = AWAITING_CANCEL_CONNECT_ACK; |
| 203 ack_result_ = result; | 204 ack_result_ = result; |
| 204 } | 205 } |
| 205 | 206 |
| 206 void SlaveConnectionManager::ConnectOnPrivateThread( | 207 void SlaveConnectionManager::ConnectOnPrivateThread( |
| 207 const ConnectionIdentifier& connection_id, | 208 const ConnectionIdentifier& connection_id, |
| 208 Result* result, | 209 Result* result, |
| 209 ProcessIdentifier* peer_process_identifier, | 210 ProcessIdentifier* peer_process_identifier, |
| 210 bool* is_first, | 211 bool* is_first, |
| 211 embedder::ScopedPlatformHandle* platform_handle) { | 212 ScopedPlatformHandle* platform_handle) { |
| 212 DCHECK(result); | 213 DCHECK(result); |
| 213 AssertOnPrivateThread(); | 214 AssertOnPrivateThread(); |
| 214 // This should only posted (from another thread, to |private_thread_|) with | 215 // This should only posted (from another thread, to |private_thread_|) with |
| 215 // the lock held (until this thread triggers |event_|). | 216 // the lock held (until this thread triggers |event_|). |
| 216 DCHECK(!mutex_.TryLock()); | 217 DCHECK(!mutex_.TryLock()); |
| 217 DCHECK_EQ(awaiting_ack_type_, NOT_AWAITING_ACK); | 218 DCHECK_EQ(awaiting_ack_type_, NOT_AWAITING_ACK); |
| 218 | 219 |
| 219 DVLOG(1) << "Sending Connect: connection ID " << connection_id.ToString(); | 220 DVLOG(1) << "Sending Connect: connection ID " << connection_id.ToString(); |
| 220 if (!raw_channel_->WriteMessage(util::MakeUnique<MessageInTransit>( | 221 if (!raw_channel_->WriteMessage(util::MakeUnique<MessageInTransit>( |
| 221 MessageInTransit::Type::CONNECTION_MANAGER, | 222 MessageInTransit::Type::CONNECTION_MANAGER, |
| 222 MessageInTransit::Subtype::CONNECTION_MANAGER_CONNECT, | 223 MessageInTransit::Subtype::CONNECTION_MANAGER_CONNECT, |
| 223 sizeof(connection_id), &connection_id))) { | 224 sizeof(connection_id), &connection_id))) { |
| 224 // Don't tear things down; possibly we'll still read some messages. | 225 // Don't tear things down; possibly we'll still read some messages. |
| 225 *result = Result::FAILURE; | 226 *result = Result::FAILURE; |
| 226 platform_handle->reset(); | 227 platform_handle->reset(); |
| 227 event_.Signal(); | 228 event_.Signal(); |
| 228 return; | 229 return; |
| 229 } | 230 } |
| 230 awaiting_ack_type_ = AWAITING_CONNECT_ACK; | 231 awaiting_ack_type_ = AWAITING_CONNECT_ACK; |
| 231 ack_result_ = result; | 232 ack_result_ = result; |
| 232 ack_peer_process_identifier_ = peer_process_identifier; | 233 ack_peer_process_identifier_ = peer_process_identifier; |
| 233 ack_is_first_ = is_first; | 234 ack_is_first_ = is_first; |
| 234 ack_platform_handle_ = platform_handle; | 235 ack_platform_handle_ = platform_handle; |
| 235 } | 236 } |
| 236 | 237 |
| 237 void SlaveConnectionManager::OnReadMessage( | 238 void SlaveConnectionManager::OnReadMessage( |
| 238 const MessageInTransit::View& message_view, | 239 const MessageInTransit::View& message_view, |
| 239 embedder::ScopedPlatformHandleVectorPtr platform_handles) { | 240 std::unique_ptr<std::vector<ScopedPlatformHandle>> platform_handles) { |
| 240 AssertOnPrivateThread(); | 241 AssertOnPrivateThread(); |
| 241 | 242 |
| 242 // Set |*ack_result_| to failure by default. | 243 // Set |*ack_result_| to failure by default. |
| 243 *ack_result_ = Result::FAILURE; | 244 *ack_result_ = Result::FAILURE; |
| 244 | 245 |
| 245 // Note: Since we should be able to trust the master, simply crash (i.e., | 246 // Note: Since we should be able to trust the master, simply crash (i.e., |
| 246 // |CHECK()|-fail) if it sends us something invalid. | 247 // |CHECK()|-fail) if it sends us something invalid. |
| 247 | 248 |
| 248 // Unsolicited message. | 249 // Unsolicited message. |
| 249 CHECK_NE(awaiting_ack_type_, NOT_AWAITING_ACK); | 250 CHECK_NE(awaiting_ack_type_, NOT_AWAITING_ACK); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 285 case MessageInTransit::Subtype:: | 286 case MessageInTransit::Subtype:: |
| 286 CONNECTION_MANAGER_ACK_SUCCESS_CONNECT_SAME_PROCESS: | 287 CONNECTION_MANAGER_ACK_SUCCESS_CONNECT_SAME_PROCESS: |
| 287 DCHECK_EQ(num_platform_handles, 0u); | 288 DCHECK_EQ(num_platform_handles, 0u); |
| 288 *ack_result_ = Result::SUCCESS_CONNECT_SAME_PROCESS; | 289 *ack_result_ = Result::SUCCESS_CONNECT_SAME_PROCESS; |
| 289 ack_platform_handle_->reset(); | 290 ack_platform_handle_->reset(); |
| 290 break; | 291 break; |
| 291 case MessageInTransit::Subtype:: | 292 case MessageInTransit::Subtype:: |
| 292 CONNECTION_MANAGER_ACK_SUCCESS_CONNECT_NEW_CONNECTION: | 293 CONNECTION_MANAGER_ACK_SUCCESS_CONNECT_NEW_CONNECTION: |
| 293 CHECK_EQ(num_platform_handles, 1u); | 294 CHECK_EQ(num_platform_handles, 1u); |
| 294 *ack_result_ = Result::SUCCESS_CONNECT_NEW_CONNECTION; | 295 *ack_result_ = Result::SUCCESS_CONNECT_NEW_CONNECTION; |
| 295 ack_platform_handle_->reset(platform_handles->at(0)); | 296 *ack_platform_handle_ = std::move(platform_handles->at(0)); |
| 296 platform_handles->at(0) = embedder::PlatformHandle(); | |
| 297 break; | 297 break; |
| 298 case MessageInTransit::Subtype:: | 298 case MessageInTransit::Subtype:: |
| 299 CONNECTION_MANAGER_ACK_SUCCESS_CONNECT_REUSE_CONNECTION: | 299 CONNECTION_MANAGER_ACK_SUCCESS_CONNECT_REUSE_CONNECTION: |
| 300 DCHECK_EQ(num_platform_handles, 0u); | 300 DCHECK_EQ(num_platform_handles, 0u); |
| 301 *ack_result_ = Result::SUCCESS_CONNECT_REUSE_CONNECTION; | 301 *ack_result_ = Result::SUCCESS_CONNECT_REUSE_CONNECTION; |
| 302 ack_platform_handle_->reset(); | 302 ack_platform_handle_->reset(); |
| 303 break; | 303 break; |
| 304 default: | 304 default: |
| 305 CHECK(false); | 305 CHECK(false); |
| 306 } | 306 } |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 340 } | 340 } |
| 341 | 341 |
| 342 void SlaveConnectionManager::AssertOnPrivateThread() const { | 342 void SlaveConnectionManager::AssertOnPrivateThread() const { |
| 343 // This should only be called after |Init()| and before |Shutdown()|. | 343 // This should only be called after |Init()| and before |Shutdown()|. |
| 344 DCHECK(private_thread_.message_loop()); | 344 DCHECK(private_thread_.message_loop()); |
| 345 DCHECK_EQ(base::MessageLoop::current(), private_thread_.message_loop()); | 345 DCHECK_EQ(base::MessageLoop::current(), private_thread_.message_loop()); |
| 346 } | 346 } |
| 347 | 347 |
| 348 } // namespace system | 348 } // namespace system |
| 349 } // namespace mojo | 349 } // namespace mojo |
| OLD | NEW |