Chromium Code Reviews| 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 "ipc/ipc_mojo_bootstrap.h" | 5 #include "ipc/ipc_mojo_bootstrap.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <map> | 9 #include <map> |
| 10 #include <memory> | 10 #include <memory> |
| 11 #include <utility> | 11 #include <utility> |
| 12 #include <vector> | |
| 12 | 13 |
| 13 #include "base/callback.h" | 14 #include "base/callback.h" |
| 14 #include "base/logging.h" | 15 #include "base/logging.h" |
| 15 #include "base/macros.h" | 16 #include "base/macros.h" |
| 16 #include "base/memory/ptr_util.h" | 17 #include "base/memory/ptr_util.h" |
| 17 #include "base/process/process_handle.h" | |
| 18 #include "base/single_thread_task_runner.h" | 18 #include "base/single_thread_task_runner.h" |
| 19 #include "base/stl_util.h" | 19 #include "base/stl_util.h" |
| 20 #include "base/synchronization/lock.h" | 20 #include "base/synchronization/lock.h" |
| 21 #include "base/threading/thread_task_runner_handle.h" | 21 #include "base/threading/thread_task_runner_handle.h" |
| 22 #include "build/build_config.h" | 22 #include "build/build_config.h" |
| 23 #include "ipc/ipc_message_utils.h" | 23 #include "ipc/ipc_message_utils.h" |
| 24 #include "ipc/ipc_platform_file.h" | 24 #include "ipc/ipc_platform_file.h" |
| 25 #include "mojo/public/cpp/bindings/associated_group.h" | 25 #include "mojo/public/cpp/bindings/associated_group.h" |
| 26 #include "mojo/public/cpp/bindings/associated_group_controller.h" | 26 #include "mojo/public/cpp/bindings/associated_group_controller.h" |
| 27 #include "mojo/public/cpp/bindings/binding.h" | 27 #include "mojo/public/cpp/bindings/binding.h" |
| 28 #include "mojo/public/cpp/bindings/connector.h" | 28 #include "mojo/public/cpp/bindings/connector.h" |
| 29 #include "mojo/public/cpp/bindings/interface_endpoint_client.h" | 29 #include "mojo/public/cpp/bindings/interface_endpoint_client.h" |
| 30 #include "mojo/public/cpp/bindings/interface_endpoint_controller.h" | 30 #include "mojo/public/cpp/bindings/interface_endpoint_controller.h" |
| 31 #include "mojo/public/cpp/bindings/interface_id.h" | 31 #include "mojo/public/cpp/bindings/interface_id.h" |
| 32 #include "mojo/public/cpp/bindings/message.h" | |
| 32 #include "mojo/public/cpp/bindings/message_header_validator.h" | 33 #include "mojo/public/cpp/bindings/message_header_validator.h" |
| 33 #include "mojo/public/cpp/bindings/pipe_control_message_handler.h" | 34 #include "mojo/public/cpp/bindings/pipe_control_message_handler.h" |
| 34 #include "mojo/public/cpp/bindings/pipe_control_message_handler_delegate.h" | 35 #include "mojo/public/cpp/bindings/pipe_control_message_handler_delegate.h" |
| 35 #include "mojo/public/cpp/bindings/pipe_control_message_proxy.h" | 36 #include "mojo/public/cpp/bindings/pipe_control_message_proxy.h" |
| 36 | 37 |
| 37 namespace IPC { | 38 namespace IPC { |
| 38 | 39 |
| 39 namespace { | 40 namespace { |
| 40 | 41 |
| 41 class ChannelAssociatedGroupController | 42 class ChannelAssociatedGroupController |
| 42 : public mojo::AssociatedGroupController, | 43 : public mojo::AssociatedGroupController, |
| 43 public mojo::MessageReceiver, | 44 public mojo::MessageReceiver, |
| 44 public mojo::PipeControlMessageHandlerDelegate { | 45 public mojo::PipeControlMessageHandlerDelegate { |
| 45 public: | 46 public: |
| 46 ChannelAssociatedGroupController(bool set_interface_id_namespace_bit, | 47 ChannelAssociatedGroupController( |
| 47 mojo::ScopedMessagePipeHandle handle) | 48 bool set_interface_id_namespace_bit, |
| 49 const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner) | |
| 48 : mojo::AssociatedGroupController(base::ThreadTaskRunnerHandle::Get()), | 50 : mojo::AssociatedGroupController(base::ThreadTaskRunnerHandle::Get()), |
| 49 task_runner_(base::ThreadTaskRunnerHandle::Get()), | 51 task_runner_(ipc_task_runner), |
| 50 id_namespace_mask_(set_interface_id_namespace_bit ? | 52 proxy_task_runner_(base::ThreadTaskRunnerHandle::Get()), |
| 51 mojo::kInterfaceIdNamespaceMask : 0), | 53 set_interface_id_namespace_bit_(set_interface_id_namespace_bit), |
| 52 associated_group_(CreateAssociatedGroup()), | |
| 53 connector_(std::move(handle), mojo::Connector::SINGLE_THREADED_SEND, | |
| 54 base::ThreadTaskRunnerHandle::Get()), | |
| 55 header_validator_( | 54 header_validator_( |
| 56 "IPC::mojom::Bootstrap [master] MessageHeaderValidator", this), | 55 "IPC::mojom::Bootstrap [master] MessageHeaderValidator", this), |
| 57 control_message_handler_(this), | 56 control_message_handler_(this), |
| 58 control_message_proxy_(&connector_) { | 57 control_message_proxy_thunk_(this), |
| 59 connector_.set_incoming_receiver(&header_validator_); | 58 control_message_proxy_(&control_message_proxy_thunk_) { |
| 60 connector_.set_connection_error_handler( | 59 thread_checker_.DetachFromThread(); |
| 61 base::Bind(&ChannelAssociatedGroupController::OnPipeError, | |
| 62 base::Unretained(this))); | |
| 63 control_message_handler_.SetDescription( | 60 control_message_handler_.SetDescription( |
| 64 "IPC::mojom::Bootstrap [master] PipeControlMessageHandler"); | 61 "IPC::mojom::Bootstrap [master] PipeControlMessageHandler"); |
| 65 } | 62 } |
| 66 | 63 |
| 67 mojo::AssociatedGroup* associated_group() { return associated_group_.get(); } | 64 void Bind(mojo::ScopedMessagePipeHandle handle) { |
| 65 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 66 DCHECK(task_runner_->BelongsToCurrentThread()); | |
| 67 connector_.reset(new mojo::Connector( | |
| 68 std::move(handle), mojo::Connector::SINGLE_THREADED_SEND, | |
| 69 task_runner_)); | |
| 70 connector_->set_incoming_receiver(&header_validator_); | |
| 71 connector_->set_connection_error_handler( | |
| 72 base::Bind(&ChannelAssociatedGroupController::OnPipeError, | |
| 73 base::Unretained(this))); | |
| 74 | |
| 75 std::vector<std::unique_ptr<mojo::Message>> outgoing_messages; | |
| 76 std::swap(outgoing_messages, outgoing_messages_); | |
| 77 for (auto& message : outgoing_messages) | |
| 78 SendMessage(message.get()); | |
| 79 } | |
| 80 | |
| 81 void CreateChannelEndpoints(mojom::ChannelAssociatedPtr* sender, | |
| 82 mojom::ChannelAssociatedRequest* receiver) { | |
| 83 mojo::InterfaceId sender_id, receiver_id; | |
| 84 if (set_interface_id_namespace_bit_) { | |
| 85 sender_id = 1 | mojo::kInterfaceIdNamespaceMask; | |
| 86 receiver_id = 1; | |
| 87 } else { | |
| 88 sender_id = 1; | |
| 89 receiver_id = 1 | mojo::kInterfaceIdNamespaceMask; | |
| 90 } | |
| 91 | |
| 92 { | |
| 93 base::AutoLock locker(lock_); | |
| 94 Endpoint* sender_endpoint = new Endpoint(this, sender_id); | |
| 95 Endpoint* receiver_endpoint = new Endpoint(this, receiver_id); | |
| 96 endpoints_.insert({ sender_id, sender_endpoint }); | |
| 97 endpoints_.insert({ receiver_id, receiver_endpoint }); | |
| 98 } | |
| 99 | |
| 100 mojo::ScopedInterfaceEndpointHandle sender_handle = | |
| 101 CreateScopedInterfaceEndpointHandle(sender_id, true); | |
| 102 mojo::ScopedInterfaceEndpointHandle receiver_handle = | |
| 103 CreateScopedInterfaceEndpointHandle(receiver_id, true); | |
| 104 | |
| 105 sender->Bind(mojom::ChannelAssociatedPtrInfo(std::move(sender_handle), 0)); | |
| 106 receiver->Bind(std::move(receiver_handle)); | |
| 107 } | |
| 68 | 108 |
| 69 void ShutDown() { | 109 void ShutDown() { |
| 70 DCHECK(thread_checker_.CalledOnValidThread()); | 110 DCHECK(thread_checker_.CalledOnValidThread()); |
| 71 connector_.CloseMessagePipe(); | 111 connector_->CloseMessagePipe(); |
| 72 OnPipeError(); | 112 OnPipeError(); |
| 73 associated_group_.reset(); | 113 connector_.reset(); |
| 74 } | |
| 75 | |
| 76 void SetProxyTaskRunner( | |
| 77 scoped_refptr<base::SingleThreadTaskRunner> proxy_task_runner) { | |
| 78 proxy_task_runner_ = proxy_task_runner; | |
| 79 } | 114 } |
| 80 | 115 |
| 81 // mojo::AssociatedGroupController: | 116 // mojo::AssociatedGroupController: |
| 82 void CreateEndpointHandlePair( | 117 void CreateEndpointHandlePair( |
| 83 mojo::ScopedInterfaceEndpointHandle* local_endpoint, | 118 mojo::ScopedInterfaceEndpointHandle* local_endpoint, |
| 84 mojo::ScopedInterfaceEndpointHandle* remote_endpoint) override { | 119 mojo::ScopedInterfaceEndpointHandle* remote_endpoint) override { |
| 85 base::AutoLock locker(lock_); | 120 base::AutoLock locker(lock_); |
| 86 uint32_t id = 0; | 121 uint32_t id = 0; |
| 87 do { | 122 do { |
| 88 if (next_interface_id_ >= mojo::kInterfaceIdNamespaceMask) | 123 if (next_interface_id_ >= mojo::kInterfaceIdNamespaceMask) |
| 89 next_interface_id_ = 1; | 124 next_interface_id_ = 2; |
| 90 id = (next_interface_id_++) | id_namespace_mask_; | 125 id = next_interface_id_++; |
| 126 if (set_interface_id_namespace_bit_) | |
| 127 id |= mojo::kInterfaceIdNamespaceMask; | |
| 91 } while (ContainsKey(endpoints_, id)); | 128 } while (ContainsKey(endpoints_, id)); |
| 92 | 129 |
| 93 Endpoint* endpoint = new Endpoint(this, id); | 130 Endpoint* endpoint = new Endpoint(this, id); |
| 94 if (encountered_error_) | 131 if (encountered_error_) |
| 95 endpoint->set_peer_closed(); | 132 endpoint->set_peer_closed(); |
| 96 endpoints_.insert({ id, endpoint }); | 133 endpoints_.insert({ id, endpoint }); |
| 97 | 134 |
| 98 *local_endpoint = CreateScopedInterfaceEndpointHandle(id, true); | 135 *local_endpoint = CreateScopedInterfaceEndpointHandle(id, true); |
| 99 *remote_endpoint = CreateScopedInterfaceEndpointHandle(id, false); | 136 *remote_endpoint = CreateScopedInterfaceEndpointHandle(id, false); |
| 100 } | 137 } |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 114 } | 151 } |
| 115 | 152 |
| 116 void CloseEndpointHandle(mojo::InterfaceId id, bool is_local) override { | 153 void CloseEndpointHandle(mojo::InterfaceId id, bool is_local) override { |
| 117 if (!mojo::IsValidInterfaceId(id)) | 154 if (!mojo::IsValidInterfaceId(id)) |
| 118 return; | 155 return; |
| 119 | 156 |
| 120 base::AutoLock locker(lock_); | 157 base::AutoLock locker(lock_); |
| 121 if (!is_local) { | 158 if (!is_local) { |
| 122 DCHECK(ContainsKey(endpoints_, id)); | 159 DCHECK(ContainsKey(endpoints_, id)); |
| 123 DCHECK(!mojo::IsMasterInterfaceId(id)); | 160 DCHECK(!mojo::IsMasterInterfaceId(id)); |
| 124 NotifyEndpointClosedBeforeSent(id); | 161 control_message_proxy_.NotifyEndpointClosedBeforeSent(id); |
| 125 return; | 162 return; |
| 126 } | 163 } |
| 127 | 164 |
| 128 DCHECK(ContainsKey(endpoints_, id)); | 165 DCHECK(ContainsKey(endpoints_, id)); |
| 129 Endpoint* endpoint = endpoints_[id].get(); | 166 Endpoint* endpoint = endpoints_[id].get(); |
| 130 DCHECK(!endpoint->client()); | 167 DCHECK(!endpoint->client()); |
| 131 DCHECK(!endpoint->closed()); | 168 DCHECK(!endpoint->closed()); |
| 132 MarkClosedAndMaybeRemove(endpoint); | 169 MarkClosedAndMaybeRemove(endpoint); |
| 133 | 170 |
| 134 if (!mojo::IsMasterInterfaceId(id)) | 171 if (!mojo::IsMasterInterfaceId(id)) |
| 135 NotifyPeerEndpointClosed(id); | 172 control_message_proxy_.NotifyPeerEndpointClosed(id); |
| 136 } | 173 } |
| 137 | 174 |
| 138 mojo::InterfaceEndpointController* AttachEndpointClient( | 175 mojo::InterfaceEndpointController* AttachEndpointClient( |
| 139 const mojo::ScopedInterfaceEndpointHandle& handle, | 176 const mojo::ScopedInterfaceEndpointHandle& handle, |
| 140 mojo::InterfaceEndpointClient* client, | 177 mojo::InterfaceEndpointClient* client, |
| 141 scoped_refptr<base::SingleThreadTaskRunner> runner) override { | 178 scoped_refptr<base::SingleThreadTaskRunner> runner) override { |
| 142 const mojo::InterfaceId id = handle.id(); | 179 const mojo::InterfaceId id = handle.id(); |
| 143 | 180 |
| 144 DCHECK(mojo::IsValidInterfaceId(id)); | 181 DCHECK(mojo::IsValidInterfaceId(id)); |
| 145 DCHECK(client); | 182 DCHECK(client); |
| 146 | 183 |
| 184 scoped_refptr<ChannelAssociatedGroupController> keepalive(this); | |
|
yzshen1
2016/07/20 22:54:51
I think this is not necessary because the Interfac
Ken Rockot(use gerrit already)
2016/07/20 23:10:20
NotifyEndpointOfError may synchronously call into
| |
| 185 | |
| 147 base::AutoLock locker(lock_); | 186 base::AutoLock locker(lock_); |
| 148 DCHECK(ContainsKey(endpoints_, id)); | 187 DCHECK(ContainsKey(endpoints_, id)); |
| 149 | 188 |
| 150 Endpoint* endpoint = endpoints_[id].get(); | 189 Endpoint* endpoint = endpoints_[id].get(); |
| 151 endpoint->AttachClient(client, std::move(runner)); | 190 endpoint->AttachClient(client, std::move(runner)); |
| 152 | 191 |
| 153 if (endpoint->peer_closed()) | 192 if (endpoint->peer_closed()) |
| 154 NotifyEndpointOfError(endpoint, true /* force_async */); | 193 NotifyEndpointOfError(endpoint, true /* force_async */); |
| 155 | 194 |
| 156 return endpoint; | 195 return endpoint; |
| 157 } | 196 } |
| 158 | 197 |
| 159 void DetachEndpointClient( | 198 void DetachEndpointClient( |
| 160 const mojo::ScopedInterfaceEndpointHandle& handle) override { | 199 const mojo::ScopedInterfaceEndpointHandle& handle) override { |
| 161 const mojo::InterfaceId id = handle.id(); | 200 const mojo::InterfaceId id = handle.id(); |
| 162 | 201 |
| 163 DCHECK(mojo::IsValidInterfaceId(id)); | 202 DCHECK(mojo::IsValidInterfaceId(id)); |
| 164 | 203 |
| 165 base::AutoLock locker(lock_); | 204 base::AutoLock locker(lock_); |
| 166 DCHECK(ContainsKey(endpoints_, id)); | 205 DCHECK(ContainsKey(endpoints_, id)); |
| 167 | 206 |
| 168 Endpoint* endpoint = endpoints_[id].get(); | 207 Endpoint* endpoint = endpoints_[id].get(); |
| 169 endpoint->DetachClient(); | 208 endpoint->DetachClient(); |
| 170 } | 209 } |
| 171 | 210 |
| 172 void RaiseError() override { | 211 void RaiseError() override { |
| 173 if (task_runner_->BelongsToCurrentThread()) { | 212 if (task_runner_->BelongsToCurrentThread()) { |
| 174 connector_.RaiseError(); | 213 connector_->RaiseError(); |
| 175 } else { | 214 } else { |
| 176 task_runner_->PostTask( | 215 task_runner_->PostTask( |
| 177 FROM_HERE, | 216 FROM_HERE, |
| 178 base::Bind(&ChannelAssociatedGroupController::RaiseError, this)); | 217 base::Bind(&ChannelAssociatedGroupController::RaiseError, this)); |
| 179 } | 218 } |
| 180 } | 219 } |
| 181 | 220 |
| 182 private: | 221 private: |
| 183 class Endpoint; | 222 class Endpoint; |
| 223 class ControlMessageProxyThunk; | |
| 184 friend class Endpoint; | 224 friend class Endpoint; |
| 225 friend class ControlMessageProxyThunk; | |
| 185 | 226 |
| 186 class Endpoint : public base::RefCountedThreadSafe<Endpoint>, | 227 class Endpoint : public base::RefCountedThreadSafe<Endpoint>, |
| 187 public mojo::InterfaceEndpointController { | 228 public mojo::InterfaceEndpointController { |
| 188 public: | 229 public: |
| 189 Endpoint(ChannelAssociatedGroupController* controller, mojo::InterfaceId id) | 230 Endpoint(ChannelAssociatedGroupController* controller, mojo::InterfaceId id) |
| 190 : controller_(controller), id_(id) {} | 231 : controller_(controller), id_(id) {} |
| 191 | 232 |
| 192 mojo::InterfaceId id() const { return id_; } | 233 mojo::InterfaceId id() const { return id_; } |
| 193 | 234 |
| 194 bool closed() const { | 235 bool closed() const { |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 277 const mojo::InterfaceId id_; | 318 const mojo::InterfaceId id_; |
| 278 | 319 |
| 279 bool closed_ = false; | 320 bool closed_ = false; |
| 280 bool peer_closed_ = false; | 321 bool peer_closed_ = false; |
| 281 mojo::InterfaceEndpointClient* client_ = nullptr; | 322 mojo::InterfaceEndpointClient* client_ = nullptr; |
| 282 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; | 323 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
| 283 | 324 |
| 284 DISALLOW_COPY_AND_ASSIGN(Endpoint); | 325 DISALLOW_COPY_AND_ASSIGN(Endpoint); |
| 285 }; | 326 }; |
| 286 | 327 |
| 328 class ControlMessageProxyThunk : public MessageReceiver { | |
| 329 public: | |
| 330 explicit ControlMessageProxyThunk( | |
| 331 ChannelAssociatedGroupController* controller) | |
| 332 : controller_(controller) {} | |
| 333 | |
| 334 private: | |
| 335 // MessageReceiver: | |
| 336 bool Accept(mojo::Message* message) override { | |
| 337 return controller_->SendMessage(message); | |
| 338 } | |
| 339 | |
| 340 ChannelAssociatedGroupController* controller_; | |
| 341 | |
| 342 DISALLOW_COPY_AND_ASSIGN(ControlMessageProxyThunk); | |
| 343 }; | |
| 344 | |
| 287 ~ChannelAssociatedGroupController() override { | 345 ~ChannelAssociatedGroupController() override { |
| 288 base::AutoLock locker(lock_); | 346 base::AutoLock locker(lock_); |
| 289 | |
| 290 for (auto iter = endpoints_.begin(); iter != endpoints_.end();) { | 347 for (auto iter = endpoints_.begin(); iter != endpoints_.end();) { |
| 291 Endpoint* endpoint = iter->second.get(); | 348 Endpoint* endpoint = iter->second.get(); |
| 292 ++iter; | 349 ++iter; |
| 293 | 350 |
| 294 DCHECK(endpoint->closed()); | 351 DCHECK(endpoint->closed()); |
| 295 MarkPeerClosedAndMaybeRemove(endpoint); | 352 MarkPeerClosedAndMaybeRemove(endpoint); |
| 296 } | 353 } |
| 297 | 354 |
| 298 DCHECK(endpoints_.empty()); | 355 DCHECK(endpoints_.empty()); |
| 299 } | 356 } |
| 300 | 357 |
| 301 bool SendMessage(mojo::Message* message) { | 358 bool SendMessage(mojo::Message* message) { |
| 302 if (task_runner_->BelongsToCurrentThread()) { | 359 if (task_runner_->BelongsToCurrentThread()) { |
| 303 DCHECK(thread_checker_.CalledOnValidThread()); | 360 DCHECK(thread_checker_.CalledOnValidThread()); |
| 304 return connector_.Accept(message); | 361 if (!connector_) { |
| 362 // Pipe may not be bound yet, so we queue the message. | |
| 363 std::unique_ptr<mojo::Message> queued_message(new mojo::Message); | |
| 364 message->MoveTo(queued_message.get()); | |
| 365 outgoing_messages_.emplace_back(std::move(queued_message)); | |
| 366 return true; | |
| 367 } | |
| 368 return connector_->Accept(message); | |
| 305 } else { | 369 } else { |
| 306 // We always post tasks to the master endpoint thread when called from the | 370 // We always post tasks to the master endpoint thread when called from the |
| 307 // proxy thread in order to simulate IPC::ChannelProxy::Send behavior. | 371 // proxy thread in order to simulate IPC::ChannelProxy::Send behavior. |
| 308 DCHECK(proxy_task_runner_ && | 372 DCHECK(proxy_task_runner_ && |
| 309 proxy_task_runner_->BelongsToCurrentThread()); | 373 proxy_task_runner_->BelongsToCurrentThread()); |
| 310 std::unique_ptr<mojo::Message> passed_message(new mojo::Message); | 374 std::unique_ptr<mojo::Message> passed_message(new mojo::Message); |
| 311 message->MoveTo(passed_message.get()); | 375 message->MoveTo(passed_message.get()); |
| 312 task_runner_->PostTask( | 376 task_runner_->PostTask( |
| 313 FROM_HERE, | 377 FROM_HERE, |
| 314 base::Bind( | 378 base::Bind( |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 339 Endpoint* endpoint = iter->second.get(); | 403 Endpoint* endpoint = iter->second.get(); |
| 340 ++iter; | 404 ++iter; |
| 341 | 405 |
| 342 if (endpoint->client()) | 406 if (endpoint->client()) |
| 343 endpoints_to_notify.push_back(endpoint); | 407 endpoints_to_notify.push_back(endpoint); |
| 344 | 408 |
| 345 MarkPeerClosedAndMaybeRemove(endpoint); | 409 MarkPeerClosedAndMaybeRemove(endpoint); |
| 346 } | 410 } |
| 347 | 411 |
| 348 for (auto& endpoint : endpoints_to_notify) { | 412 for (auto& endpoint : endpoints_to_notify) { |
| 349 // Because an notification may in turn detach any endpoint, we have to | 413 // Because a notification may in turn detach any endpoint, we have to |
| 350 // check each client again here. | 414 // check each client again here. |
| 351 if (endpoint->client()) | 415 if (endpoint->client()) |
| 352 NotifyEndpointOfError(endpoint.get(), false /* force_async */); | 416 NotifyEndpointOfError(endpoint.get(), false /* force_async */); |
| 353 } | 417 } |
| 354 } | 418 } |
| 355 | 419 |
| 356 void NotifyEndpointOfError(Endpoint* endpoint, bool force_async) { | 420 void NotifyEndpointOfError(Endpoint* endpoint, bool force_async) { |
| 357 lock_.AssertAcquired(); | 421 lock_.AssertAcquired(); |
| 358 DCHECK(endpoint->task_runner() && endpoint->client()); | 422 DCHECK(endpoint->task_runner() && endpoint->client()); |
| 359 if (endpoint->task_runner()->BelongsToCurrentThread() && !force_async) { | 423 if (endpoint->task_runner()->BelongsToCurrentThread() && !force_async) { |
| 360 mojo::InterfaceEndpointClient* client = endpoint->client(); | 424 mojo::InterfaceEndpointClient* client = endpoint->client(); |
| 361 | 425 |
| 362 base::AutoUnlock unlocker(lock_); | 426 base::AutoUnlock unlocker(lock_); |
| 363 client->NotifyError(); | 427 client->NotifyError(); |
| 364 } else { | 428 } else { |
| 365 endpoint->task_runner()->PostTask( | 429 endpoint->task_runner()->PostTask( |
| 366 FROM_HERE, | 430 FROM_HERE, |
| 367 base::Bind(&ChannelAssociatedGroupController | 431 base::Bind(&ChannelAssociatedGroupController |
| 368 ::NotifyEndpointOfErrorOnEndpointThread, this, | 432 ::NotifyEndpointOfErrorOnEndpointThread, this, |
| 369 make_scoped_refptr(endpoint))); | 433 make_scoped_refptr(endpoint))); |
| 370 } | 434 } |
| 371 } | 435 } |
| 372 | 436 |
| 373 void NotifyEndpointOfErrorOnEndpointThread(scoped_refptr<Endpoint> endpoint) { | 437 void NotifyEndpointOfErrorOnEndpointThread(scoped_refptr<Endpoint> endpoint) { |
| 438 scoped_refptr<ChannelAssociatedGroupController> keepalive(this); | |
|
yzshen1
2016/07/20 22:54:51
Why do we need to keep it alive explicitly? I thou
Ken Rockot(use gerrit already)
2016/07/20 23:10:20
Ah, you are right :) Fixed.
| |
| 374 base::AutoLock locker(lock_); | 439 base::AutoLock locker(lock_); |
| 375 if (!endpoint->client()) | 440 if (!endpoint->client()) |
| 376 return; | 441 return; |
| 377 DCHECK(endpoint->task_runner()->BelongsToCurrentThread()); | 442 DCHECK(endpoint->task_runner()->BelongsToCurrentThread()); |
| 378 NotifyEndpointOfError(endpoint.get(), false /* force_async */); | 443 NotifyEndpointOfError(endpoint.get(), false /* force_async */); |
| 379 } | 444 } |
| 380 | 445 |
| 381 void MarkClosedAndMaybeRemove(Endpoint* endpoint) { | 446 void MarkClosedAndMaybeRemove(Endpoint* endpoint) { |
| 382 lock_.AssertAcquired(); | 447 lock_.AssertAcquired(); |
| 383 endpoint->set_closed(); | 448 endpoint->set_closed(); |
| 384 if (endpoint->closed() && endpoint->peer_closed()) | 449 if (endpoint->closed() && endpoint->peer_closed()) |
| 385 endpoints_.erase(endpoint->id()); | 450 endpoints_.erase(endpoint->id()); |
| 386 } | 451 } |
| 387 | 452 |
| 388 void MarkPeerClosedAndMaybeRemove(Endpoint* endpoint) { | 453 void MarkPeerClosedAndMaybeRemove(Endpoint* endpoint) { |
| 389 lock_.AssertAcquired(); | 454 lock_.AssertAcquired(); |
| 390 endpoint->set_peer_closed(); | 455 endpoint->set_peer_closed(); |
| 391 if (endpoint->closed() && endpoint->peer_closed()) | 456 if (endpoint->closed() && endpoint->peer_closed()) |
| 392 endpoints_.erase(endpoint->id()); | 457 endpoints_.erase(endpoint->id()); |
| 393 } | 458 } |
| 394 | 459 |
| 395 void NotifyPeerEndpointClosed(mojo::InterfaceId id) { | |
| 396 if (task_runner_->BelongsToCurrentThread()) { | |
| 397 if (connector_.is_valid()) | |
| 398 control_message_proxy_.NotifyPeerEndpointClosed(id); | |
| 399 } else { | |
| 400 task_runner_->PostTask( | |
| 401 FROM_HERE, | |
| 402 base::Bind(&ChannelAssociatedGroupController | |
| 403 ::NotifyPeerEndpointClosed, this, id)); | |
| 404 } | |
| 405 } | |
| 406 | |
| 407 void NotifyEndpointClosedBeforeSent(mojo::InterfaceId id) { | |
| 408 if (task_runner_->BelongsToCurrentThread()) { | |
| 409 if (connector_.is_valid()) | |
| 410 control_message_proxy_.NotifyEndpointClosedBeforeSent(id); | |
| 411 } else { | |
| 412 task_runner_->PostTask( | |
| 413 FROM_HERE, | |
| 414 base::Bind(&ChannelAssociatedGroupController | |
| 415 ::NotifyEndpointClosedBeforeSent, this, id)); | |
| 416 } | |
| 417 } | |
| 418 | |
| 419 Endpoint* FindOrInsertEndpoint(mojo::InterfaceId id, bool* inserted) { | 460 Endpoint* FindOrInsertEndpoint(mojo::InterfaceId id, bool* inserted) { |
| 420 lock_.AssertAcquired(); | 461 lock_.AssertAcquired(); |
| 421 DCHECK(!inserted || !*inserted); | 462 DCHECK(!inserted || !*inserted); |
| 422 | 463 |
| 423 auto iter = endpoints_.find(id); | 464 auto iter = endpoints_.find(id); |
| 424 if (iter != endpoints_.end()) | 465 if (iter != endpoints_.end()) |
| 425 return iter->second.get(); | 466 return iter->second.get(); |
| 426 | 467 |
| 427 Endpoint* endpoint = new Endpoint(this, id); | 468 Endpoint* endpoint = new Endpoint(this, id); |
| 428 endpoints_.insert({ id, endpoint }); | 469 endpoints_.insert({ id, endpoint }); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 503 RaiseError(); | 544 RaiseError(); |
| 504 } | 545 } |
| 505 | 546 |
| 506 Endpoint* GetEndpointForDispatch(mojo::InterfaceId id) { | 547 Endpoint* GetEndpointForDispatch(mojo::InterfaceId id) { |
| 507 lock_.AssertAcquired(); | 548 lock_.AssertAcquired(); |
| 508 bool inserted = false; | 549 bool inserted = false; |
| 509 Endpoint* endpoint = FindOrInsertEndpoint(id, &inserted); | 550 Endpoint* endpoint = FindOrInsertEndpoint(id, &inserted); |
| 510 if (inserted) { | 551 if (inserted) { |
| 511 MarkClosedAndMaybeRemove(endpoint); | 552 MarkClosedAndMaybeRemove(endpoint); |
| 512 if (!mojo::IsMasterInterfaceId(id)) | 553 if (!mojo::IsMasterInterfaceId(id)) |
| 513 NotifyPeerEndpointClosed(id); | 554 control_message_proxy_.NotifyPeerEndpointClosed(id); |
| 514 return nullptr; | 555 return nullptr; |
| 515 } | 556 } |
| 516 | 557 |
| 517 if (endpoint->closed()) | 558 if (endpoint->closed()) |
| 518 return nullptr; | 559 return nullptr; |
| 519 | 560 |
| 520 return endpoint; | 561 return endpoint; |
| 521 } | 562 } |
| 522 | 563 |
| 523 // mojo::PipeControlMessageHandlerDelegate: | 564 // mojo::PipeControlMessageHandlerDelegate: |
| 524 bool OnPeerAssociatedEndpointClosed(mojo::InterfaceId id) override { | 565 bool OnPeerAssociatedEndpointClosed(mojo::InterfaceId id) override { |
| 525 DCHECK(thread_checker_.CalledOnValidThread()); | 566 DCHECK(thread_checker_.CalledOnValidThread()); |
| 526 | 567 |
| 527 if (mojo::IsMasterInterfaceId(id)) | 568 if (mojo::IsMasterInterfaceId(id)) |
| 528 return false; | 569 return false; |
| 529 | 570 |
| 571 scoped_refptr<ChannelAssociatedGroupController> keepalive(this); | |
| 530 base::AutoLock locker(lock_); | 572 base::AutoLock locker(lock_); |
| 531 scoped_refptr<Endpoint> endpoint = FindOrInsertEndpoint(id, nullptr); | 573 scoped_refptr<Endpoint> endpoint = FindOrInsertEndpoint(id, nullptr); |
| 532 if (!endpoint->peer_closed()) { | 574 if (!endpoint->peer_closed()) { |
| 533 if (endpoint->client()) | 575 if (endpoint->client()) |
| 534 NotifyEndpointOfError(endpoint.get(), false /* force_async */); | 576 NotifyEndpointOfError(endpoint.get(), false /* force_async */); |
| 535 MarkPeerClosedAndMaybeRemove(endpoint.get()); | 577 MarkPeerClosedAndMaybeRemove(endpoint.get()); |
| 536 } | 578 } |
| 537 | 579 |
| 538 return true; | 580 return true; |
| 539 } | 581 } |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 550 MarkClosedAndMaybeRemove(endpoint); | 592 MarkClosedAndMaybeRemove(endpoint); |
| 551 control_message_proxy_.NotifyPeerEndpointClosed(id); | 593 control_message_proxy_.NotifyPeerEndpointClosed(id); |
| 552 return true; | 594 return true; |
| 553 } | 595 } |
| 554 | 596 |
| 555 // Checked in places which must be run on the master endpoint's thread. | 597 // Checked in places which must be run on the master endpoint's thread. |
| 556 base::ThreadChecker thread_checker_; | 598 base::ThreadChecker thread_checker_; |
| 557 | 599 |
| 558 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; | 600 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
| 559 scoped_refptr<base::SingleThreadTaskRunner> proxy_task_runner_; | 601 scoped_refptr<base::SingleThreadTaskRunner> proxy_task_runner_; |
| 560 const uint32_t id_namespace_mask_; | 602 const bool set_interface_id_namespace_bit_; |
| 561 std::unique_ptr<mojo::AssociatedGroup> associated_group_; | 603 std::unique_ptr<mojo::Connector> connector_; |
| 562 mojo::Connector connector_; | |
| 563 mojo::MessageHeaderValidator header_validator_; | 604 mojo::MessageHeaderValidator header_validator_; |
| 564 mojo::PipeControlMessageHandler control_message_handler_; | 605 mojo::PipeControlMessageHandler control_message_handler_; |
| 606 ControlMessageProxyThunk control_message_proxy_thunk_; | |
| 607 mojo::PipeControlMessageProxy control_message_proxy_; | |
| 608 | |
| 609 // Outgoing messages that were sent before this controller was bound to a | |
| 610 // real message pipe. | |
| 611 std::vector<std::unique_ptr<mojo::Message>> outgoing_messages_; | |
| 565 | 612 |
| 566 // Guards the fields below for thread-safe access. | 613 // Guards the fields below for thread-safe access. |
| 567 base::Lock lock_; | 614 base::Lock lock_; |
| 568 | 615 |
| 569 bool encountered_error_ = false; | 616 bool encountered_error_ = false; |
| 570 uint32_t next_interface_id_ = 1; | 617 |
| 618 // ID #1 is reserved for the mojom::Channel interface. | |
| 619 uint32_t next_interface_id_ = 2; | |
| 620 | |
| 571 std::map<uint32_t, scoped_refptr<Endpoint>> endpoints_; | 621 std::map<uint32_t, scoped_refptr<Endpoint>> endpoints_; |
| 572 mojo::PipeControlMessageProxy control_message_proxy_; | |
| 573 | 622 |
| 574 DISALLOW_COPY_AND_ASSIGN(ChannelAssociatedGroupController); | 623 DISALLOW_COPY_AND_ASSIGN(ChannelAssociatedGroupController); |
| 575 }; | 624 }; |
| 576 | 625 |
| 577 class BootstrapMasterProxy { | 626 class MojoBootstrapImpl : public MojoBootstrap { |
| 578 public: | 627 public: |
| 579 BootstrapMasterProxy() {} | 628 MojoBootstrapImpl( |
| 580 ~BootstrapMasterProxy() { | 629 mojo::ScopedMessagePipeHandle handle, |
| 581 endpoint_client_.reset(); | 630 Delegate* delegate, |
| 582 proxy_.reset(); | 631 const scoped_refptr<ChannelAssociatedGroupController> controller) |
| 583 if (controller_) | 632 : controller_(controller), |
| 584 controller_->ShutDown(); | 633 handle_(std::move(handle)), |
| 634 delegate_(delegate) { | |
| 635 associated_group_ = controller_->CreateAssociatedGroup(); | |
| 585 } | 636 } |
| 586 | 637 |
| 587 void Bind(mojo::ScopedMessagePipeHandle handle) { | 638 ~MojoBootstrapImpl() override { |
| 588 DCHECK(!controller_); | 639 controller_->ShutDown(); |
| 589 controller_ = new ChannelAssociatedGroupController(true, std::move(handle)); | |
| 590 endpoint_client_.reset(new mojo::InterfaceEndpointClient( | |
| 591 controller_->CreateLocalEndpointHandle(mojo::kMasterInterfaceId), | |
| 592 nullptr, | |
| 593 base::MakeUnique<typename mojom::Bootstrap::ResponseValidator_>(), | |
| 594 false, base::ThreadTaskRunnerHandle::Get())); | |
| 595 proxy_.reset(new mojom::BootstrapProxy(endpoint_client_.get())); | |
| 596 proxy_->serialization_context()->group_controller = controller_; | |
| 597 } | |
| 598 | |
| 599 void set_connection_error_handler(const base::Closure& handler) { | |
| 600 DCHECK(endpoint_client_); | |
| 601 endpoint_client_->set_connection_error_handler(handler); | |
| 602 } | |
| 603 | |
| 604 mojo::AssociatedGroup* associated_group() { | |
| 605 DCHECK(controller_); | |
| 606 return controller_->associated_group(); | |
| 607 } | |
| 608 | |
| 609 ChannelAssociatedGroupController* controller() { | |
| 610 DCHECK(controller_); | |
| 611 return controller_.get(); | |
| 612 } | |
| 613 | |
| 614 mojom::Bootstrap* operator->() { | |
| 615 DCHECK(proxy_); | |
| 616 return proxy_.get(); | |
| 617 } | 640 } |
| 618 | 641 |
| 619 private: | 642 private: |
| 620 std::unique_ptr<mojom::BootstrapProxy> proxy_; | 643 // MojoBootstrap: |
| 644 void Connect() override { | |
| 645 controller_->Bind(std::move(handle_)); | |
| 646 | |
| 647 IPC::mojom::ChannelAssociatedPtr sender; | |
| 648 IPC::mojom::ChannelAssociatedRequest receiver; | |
| 649 controller_->CreateChannelEndpoints(&sender, &receiver); | |
| 650 | |
| 651 delegate_->OnPipesAvailable(std::move(sender), std::move(receiver)); | |
| 652 } | |
| 653 | |
| 654 mojo::AssociatedGroup* GetAssociatedGroup() override { | |
| 655 return associated_group_.get(); | |
| 656 } | |
| 657 | |
| 621 scoped_refptr<ChannelAssociatedGroupController> controller_; | 658 scoped_refptr<ChannelAssociatedGroupController> controller_; |
| 622 std::unique_ptr<mojo::InterfaceEndpointClient> endpoint_client_; | |
| 623 | 659 |
| 624 DISALLOW_COPY_AND_ASSIGN(BootstrapMasterProxy); | 660 mojo::ScopedMessagePipeHandle handle_; |
| 661 Delegate* delegate_; | |
| 662 std::unique_ptr<mojo::AssociatedGroup> associated_group_; | |
| 663 | |
| 664 DISALLOW_COPY_AND_ASSIGN(MojoBootstrapImpl); | |
| 625 }; | 665 }; |
| 626 | 666 |
| 627 class BootstrapMasterBinding { | |
| 628 public: | |
| 629 explicit BootstrapMasterBinding(mojom::Bootstrap* impl) { | |
| 630 stub_.set_sink(impl); | |
| 631 } | |
| 632 | |
| 633 ~BootstrapMasterBinding() { | |
| 634 endpoint_client_.reset(); | |
| 635 if (controller_) | |
| 636 controller_->ShutDown(); | |
| 637 } | |
| 638 | |
| 639 void set_connection_error_handler(const base::Closure& handler) { | |
| 640 DCHECK(endpoint_client_); | |
| 641 endpoint_client_->set_connection_error_handler(handler); | |
| 642 } | |
| 643 | |
| 644 mojo::AssociatedGroup* associated_group() { | |
| 645 DCHECK(controller_); | |
| 646 return controller_->associated_group(); | |
| 647 } | |
| 648 | |
| 649 ChannelAssociatedGroupController* controller() { | |
| 650 DCHECK(controller_); | |
| 651 return controller_.get(); | |
| 652 } | |
| 653 | |
| 654 void Bind(mojo::ScopedMessagePipeHandle handle) { | |
| 655 DCHECK(!controller_); | |
| 656 controller_ = | |
| 657 new ChannelAssociatedGroupController(false, std::move(handle)); | |
| 658 stub_.serialization_context()->group_controller = controller_; | |
| 659 | |
| 660 endpoint_client_.reset(new mojo::InterfaceEndpointClient( | |
| 661 controller_->CreateLocalEndpointHandle(mojo::kMasterInterfaceId), | |
| 662 &stub_, | |
| 663 base::MakeUnique<typename mojom::Bootstrap::RequestValidator_>(), | |
| 664 false, base::ThreadTaskRunnerHandle::Get())); | |
| 665 } | |
| 666 | |
| 667 private: | |
| 668 mojom::BootstrapStub stub_; | |
| 669 scoped_refptr<ChannelAssociatedGroupController> controller_; | |
| 670 std::unique_ptr<mojo::InterfaceEndpointClient> endpoint_client_; | |
| 671 | |
| 672 DISALLOW_COPY_AND_ASSIGN(BootstrapMasterBinding); | |
| 673 }; | |
| 674 | |
| 675 // MojoBootstrap for the server process. You should create the instance | |
| 676 // using MojoBootstrap::Create(). | |
| 677 class MojoServerBootstrap : public MojoBootstrap { | |
| 678 public: | |
| 679 MojoServerBootstrap(); | |
| 680 | |
| 681 private: | |
| 682 // MojoBootstrap implementation. | |
| 683 void Connect() override; | |
| 684 | |
| 685 mojo::AssociatedGroup* GetAssociatedGroup() override { | |
| 686 return bootstrap_.associated_group(); | |
| 687 } | |
| 688 | |
| 689 void SetProxyTaskRunner( | |
| 690 scoped_refptr<base::SingleThreadTaskRunner> task_runner) override { | |
| 691 bootstrap_.controller()->SetProxyTaskRunner(task_runner); | |
| 692 } | |
| 693 | |
| 694 void OnInitDone(int32_t peer_pid); | |
| 695 | |
| 696 BootstrapMasterProxy bootstrap_; | |
| 697 IPC::mojom::ChannelAssociatedPtrInfo send_channel_; | |
| 698 IPC::mojom::ChannelAssociatedRequest receive_channel_request_; | |
| 699 | |
| 700 DISALLOW_COPY_AND_ASSIGN(MojoServerBootstrap); | |
| 701 }; | |
| 702 | |
| 703 MojoServerBootstrap::MojoServerBootstrap() = default; | |
| 704 | |
| 705 void MojoServerBootstrap::Connect() { | |
| 706 DCHECK_EQ(state(), STATE_INITIALIZED); | |
| 707 | |
| 708 bootstrap_.Bind(TakeHandle()); | |
| 709 bootstrap_.set_connection_error_handler( | |
| 710 base::Bind(&MojoServerBootstrap::Fail, base::Unretained(this))); | |
| 711 | |
| 712 IPC::mojom::ChannelAssociatedRequest send_channel_request; | |
| 713 IPC::mojom::ChannelAssociatedPtrInfo receive_channel; | |
| 714 | |
| 715 bootstrap_.associated_group()->CreateAssociatedInterface( | |
| 716 mojo::AssociatedGroup::WILL_PASS_REQUEST, &send_channel_, | |
| 717 &send_channel_request); | |
| 718 bootstrap_.associated_group()->CreateAssociatedInterface( | |
| 719 mojo::AssociatedGroup::WILL_PASS_PTR, &receive_channel, | |
| 720 &receive_channel_request_); | |
| 721 | |
| 722 bootstrap_->Init( | |
| 723 std::move(send_channel_request), std::move(receive_channel), | |
| 724 GetSelfPID(), | |
| 725 base::Bind(&MojoServerBootstrap::OnInitDone, base::Unretained(this))); | |
| 726 | |
| 727 set_state(STATE_WAITING_ACK); | |
| 728 } | |
| 729 | |
| 730 void MojoServerBootstrap::OnInitDone(int32_t peer_pid) { | |
| 731 if (state() != STATE_WAITING_ACK) { | |
| 732 set_state(STATE_ERROR); | |
| 733 LOG(ERROR) << "Got inconsistent message from client."; | |
| 734 return; | |
| 735 } | |
| 736 | |
| 737 set_state(STATE_READY); | |
| 738 bootstrap_.set_connection_error_handler(base::Closure()); | |
| 739 delegate()->OnPipesAvailable(std::move(send_channel_), | |
| 740 std::move(receive_channel_request_), peer_pid); | |
| 741 } | |
| 742 | |
| 743 // MojoBootstrap for client processes. You should create the instance | |
| 744 // using MojoBootstrap::Create(). | |
| 745 class MojoClientBootstrap : public MojoBootstrap, public mojom::Bootstrap { | |
| 746 public: | |
| 747 MojoClientBootstrap(); | |
| 748 | |
| 749 private: | |
| 750 // MojoBootstrap implementation. | |
| 751 void Connect() override; | |
| 752 | |
| 753 mojo::AssociatedGroup* GetAssociatedGroup() override { | |
| 754 return binding_.associated_group(); | |
| 755 } | |
| 756 | |
| 757 void SetProxyTaskRunner( | |
| 758 scoped_refptr<base::SingleThreadTaskRunner> task_runner) override { | |
| 759 binding_.controller()->SetProxyTaskRunner(task_runner); | |
| 760 } | |
| 761 | |
| 762 // mojom::Bootstrap implementation. | |
| 763 void Init(mojom::ChannelAssociatedRequest receive_channel, | |
| 764 mojom::ChannelAssociatedPtrInfo send_channel, | |
| 765 int32_t peer_pid, | |
| 766 const InitCallback& callback) override; | |
| 767 | |
| 768 BootstrapMasterBinding binding_; | |
| 769 | |
| 770 DISALLOW_COPY_AND_ASSIGN(MojoClientBootstrap); | |
| 771 }; | |
| 772 | |
| 773 MojoClientBootstrap::MojoClientBootstrap() : binding_(this) {} | |
| 774 | |
| 775 void MojoClientBootstrap::Connect() { | |
| 776 binding_.Bind(TakeHandle()); | |
| 777 binding_.set_connection_error_handler( | |
| 778 base::Bind(&MojoClientBootstrap::Fail, base::Unretained(this))); | |
| 779 } | |
| 780 | |
| 781 void MojoClientBootstrap::Init(mojom::ChannelAssociatedRequest receive_channel, | |
| 782 mojom::ChannelAssociatedPtrInfo send_channel, | |
| 783 int32_t peer_pid, | |
| 784 const InitCallback& callback) { | |
| 785 callback.Run(GetSelfPID()); | |
| 786 set_state(STATE_READY); | |
| 787 binding_.set_connection_error_handler(base::Closure()); | |
| 788 delegate()->OnPipesAvailable(std::move(send_channel), | |
| 789 std::move(receive_channel), peer_pid); | |
| 790 } | |
| 791 | |
| 792 } // namespace | 667 } // namespace |
| 793 | 668 |
| 794 // MojoBootstrap | |
| 795 | |
| 796 // static | 669 // static |
| 797 std::unique_ptr<MojoBootstrap> MojoBootstrap::Create( | 670 std::unique_ptr<MojoBootstrap> MojoBootstrap::Create( |
| 798 mojo::ScopedMessagePipeHandle handle, | 671 mojo::ScopedMessagePipeHandle handle, |
| 799 Channel::Mode mode, | 672 Channel::Mode mode, |
| 800 Delegate* delegate) { | 673 Delegate* delegate, |
| 801 CHECK(mode == Channel::MODE_CLIENT || mode == Channel::MODE_SERVER); | 674 const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner) { |
| 802 std::unique_ptr<MojoBootstrap> self = | 675 return base::MakeUnique<MojoBootstrapImpl>( |
| 803 mode == Channel::MODE_CLIENT | 676 std::move(handle), delegate, |
| 804 ? std::unique_ptr<MojoBootstrap>(new MojoClientBootstrap) | 677 new ChannelAssociatedGroupController(mode == Channel::MODE_SERVER, |
| 805 : std::unique_ptr<MojoBootstrap>(new MojoServerBootstrap); | 678 ipc_task_runner)); |
| 806 | |
| 807 self->Init(std::move(handle), delegate); | |
| 808 return self; | |
| 809 } | |
| 810 | |
| 811 MojoBootstrap::MojoBootstrap() : delegate_(NULL), state_(STATE_INITIALIZED) { | |
| 812 } | |
| 813 | |
| 814 MojoBootstrap::~MojoBootstrap() {} | |
| 815 | |
| 816 void MojoBootstrap::Init(mojo::ScopedMessagePipeHandle handle, | |
| 817 Delegate* delegate) { | |
| 818 handle_ = std::move(handle); | |
| 819 delegate_ = delegate; | |
| 820 } | |
| 821 | |
| 822 base::ProcessId MojoBootstrap::GetSelfPID() const { | |
| 823 #if defined(OS_LINUX) | |
| 824 if (int global_pid = Channel::GetGlobalPid()) | |
| 825 return global_pid; | |
| 826 #endif // OS_LINUX | |
| 827 #if defined(OS_NACL) | |
| 828 return -1; | |
| 829 #else | |
| 830 return base::GetCurrentProcId(); | |
| 831 #endif // defined(OS_NACL) | |
| 832 } | |
| 833 | |
| 834 void MojoBootstrap::Fail() { | |
| 835 set_state(STATE_ERROR); | |
| 836 delegate()->OnBootstrapError(); | |
| 837 } | |
| 838 | |
| 839 bool MojoBootstrap::HasFailed() const { | |
| 840 return state() == STATE_ERROR; | |
| 841 } | |
| 842 | |
| 843 mojo::ScopedMessagePipeHandle MojoBootstrap::TakeHandle() { | |
| 844 return std::move(handle_); | |
| 845 } | 679 } |
| 846 | 680 |
| 847 } // namespace IPC | 681 } // namespace IPC |
| OLD | NEW |