| 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 "services/service_manager/service_manager.h" | 5 #include "services/service_manager/service_manager.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 94 control_binding_(this), | 94 control_binding_(this), |
| 95 state_(State::IDLE), | 95 state_(State::IDLE), |
| 96 weak_factory_(this) { | 96 weak_factory_(this) { |
| 97 if (identity_.name() == service_manager::mojom::kServiceName || | 97 if (identity_.name() == service_manager::mojom::kServiceName || |
| 98 identity_.name() == catalog::mojom::kServiceName) { | 98 identity_.name() == catalog::mojom::kServiceName) { |
| 99 pid_ = base::Process::Current().Pid(); | 99 pid_ = base::Process::Current().Pid(); |
| 100 } | 100 } |
| 101 DCHECK_NE(mojom::kInvalidInstanceID, id_); | 101 DCHECK_NE(mojom::kInvalidInstanceID, id_); |
| 102 } | 102 } |
| 103 | 103 |
| 104 ~Instance() override { | 104 void Stop() { |
| 105 // Shutdown all bindings before we close the runner. This way the process | 105 // Shutdown all bindings. This way the process should see the pipes closed |
| 106 // should see the pipes closed and exit, as well as waking up any potential | 106 // and exit, as well as waking up any potential |
| 107 // sync/WaitForIncomingResponse(). | 107 // sync/WaitForIncomingResponse(). |
| 108 service_.reset(); | 108 service_.reset(); |
| 109 if (pid_receiver_binding_.is_bound()) | 109 if (pid_receiver_binding_.is_bound()) |
| 110 pid_receiver_binding_.Close(); | 110 pid_receiver_binding_.Close(); |
| 111 connectors_.CloseAllBindings(); | 111 connectors_.CloseAllBindings(); |
| 112 service_manager_bindings_.CloseAllBindings(); | 112 service_manager_bindings_.CloseAllBindings(); |
| 113 service_manager_->OnInstanceUnreachable(this); | 113 service_manager_->OnInstanceUnreachable(this); |
| 114 | 114 |
| 115 if (state_ == State::STARTING) { | 115 if (state_ == State::STARTING) { |
| 116 service_manager_->NotifyServiceFailedToStart(identity_); | 116 service_manager_->NotifyServiceFailedToStart(identity_); |
| 117 } else { | 117 } else { |
| 118 // Notify the ServiceManager that this Instance is really going away. | 118 // Notify the ServiceManager that this Instance is really going away. |
| 119 service_manager_->OnInstanceStopped(identity_); | 119 service_manager_->OnInstanceStopped(identity_); |
| 120 } | 120 } |
| 121 } |
| 122 |
| 123 ~Instance() override { |
| 124 Stop(); |
| 121 | 125 |
| 122 // Release |runner_| so that if we are called back to OnRunnerCompleted() | 126 // Release |runner_| so that if we are called back to OnRunnerCompleted() |
| 123 // we know we're in the destructor. | 127 // we know we're in the destructor. |
| 124 std::unique_ptr<NativeRunner> runner = std::move(runner_); | 128 std::unique_ptr<NativeRunner> runner = std::move(runner_); |
| 125 runner.reset(); | 129 runner.reset(); |
| 126 } | 130 } |
| 127 | 131 |
| 128 Instance* parent() const { return parent_; } | |
| 129 | |
| 130 void AddChild(std::unique_ptr<Instance> child) { | |
| 131 child->parent_ = this; | |
| 132 children_.insert(std::make_pair(child.get(), std::move(child))); | |
| 133 } | |
| 134 | |
| 135 void RemoveChild(Instance* child) { | |
| 136 auto it = children_.find(child); | |
| 137 DCHECK(it != children_.end()); | |
| 138 | |
| 139 // Deletes |child|. | |
| 140 children_.erase(it); | |
| 141 } | |
| 142 | |
| 143 bool ConnectToService(std::unique_ptr<ConnectParams>* connect_params) { | 132 bool ConnectToService(std::unique_ptr<ConnectParams>* connect_params) { |
| 144 if (!service_.is_bound()) | 133 if (!service_.is_bound()) |
| 145 return false; | 134 return false; |
| 146 | 135 |
| 147 std::unique_ptr<ConnectParams> params(std::move(*connect_params)); | 136 std::unique_ptr<ConnectParams> params(std::move(*connect_params)); |
| 148 if (!params->connect_callback().is_null()) { | 137 if (!params->connect_callback().is_null()) { |
| 149 params->connect_callback().Run(mojom::ConnectResult::SUCCEEDED, | 138 params->connect_callback().Run(mojom::ConnectResult::SUCCEEDED, |
| 150 identity_.user_id()); | 139 identity_.user_id()); |
| 151 } | 140 } |
| 152 | 141 |
| (...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 466 const InterfaceProviderSpecMap interface_provider_specs_; | 455 const InterfaceProviderSpecMap interface_provider_specs_; |
| 467 const InterfaceProviderSpec empty_spec_; | 456 const InterfaceProviderSpec empty_spec_; |
| 468 const bool allow_any_application_; | 457 const bool allow_any_application_; |
| 469 std::unique_ptr<NativeRunner> runner_; | 458 std::unique_ptr<NativeRunner> runner_; |
| 470 mojom::ServicePtr service_; | 459 mojom::ServicePtr service_; |
| 471 mojo::Binding<mojom::PIDReceiver> pid_receiver_binding_; | 460 mojo::Binding<mojom::PIDReceiver> pid_receiver_binding_; |
| 472 mojo::BindingSet<mojom::Connector> connectors_; | 461 mojo::BindingSet<mojom::Connector> connectors_; |
| 473 mojo::BindingSet<mojom::ServiceManager> service_manager_bindings_; | 462 mojo::BindingSet<mojom::ServiceManager> service_manager_bindings_; |
| 474 mojo::AssociatedBinding<mojom::ServiceControl> control_binding_; | 463 mojo::AssociatedBinding<mojom::ServiceControl> control_binding_; |
| 475 base::ProcessId pid_ = base::kNullProcessId; | 464 base::ProcessId pid_ = base::kNullProcessId; |
| 476 Instance* parent_ = nullptr; | |
| 477 InstanceMap children_; | |
| 478 State state_; | 465 State state_; |
| 479 | 466 |
| 480 // The number of outstanding OnConnect requests which are in flight. | 467 // The number of outstanding OnConnect requests which are in flight. |
| 481 int pending_service_connections_ = 0; | 468 int pending_service_connections_ = 0; |
| 482 | 469 |
| 483 base::WeakPtrFactory<Instance> weak_factory_; | 470 base::WeakPtrFactory<Instance> weak_factory_; |
| 484 | 471 |
| 485 DISALLOW_COPY_AND_ASSIGN(Instance); | 472 DISALLOW_COPY_AND_ASSIGN(Instance); |
| 486 }; | 473 }; |
| 487 | 474 |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 560 | 547 |
| 561 if (catalog) | 548 if (catalog) |
| 562 InitCatalog(std::move(catalog)); | 549 InitCatalog(std::move(catalog)); |
| 563 } | 550 } |
| 564 | 551 |
| 565 ServiceManager::~ServiceManager() { | 552 ServiceManager::~ServiceManager() { |
| 566 // Ensure we tear down the ServiceManager instance last. This is to avoid | 553 // Ensure we tear down the ServiceManager instance last. This is to avoid |
| 567 // hitting bindings DCHECKs, since the ServiceManager or Catalog may at any | 554 // hitting bindings DCHECKs, since the ServiceManager or Catalog may at any |
| 568 // given time own in-flight responders for Instances' Connector requests. | 555 // given time own in-flight responders for Instances' Connector requests. |
| 569 std::unique_ptr<Instance> service_manager_instance; | 556 std::unique_ptr<Instance> service_manager_instance; |
| 570 auto iter = root_instances_.find(service_manager_instance_); | 557 auto iter = instances_.find(service_manager_instance_); |
| 571 DCHECK(iter != root_instances_.end()); | 558 DCHECK(iter != instances_.end()); |
| 572 service_manager_instance = std::move(iter->second); | 559 service_manager_instance = std::move(iter->second); |
| 573 | 560 |
| 574 root_instances_.clear(); | 561 // Stop all of the instances before destroying any of them. This ensures that |
| 562 // all Services will receive connection errors and avoids possible deadlock in |
| 563 // the case where one Instance's destructor blocks waiting for its Runner to |
| 564 // quit, while that Runner's corresponding Service blocks its shutdown on a |
| 565 // distinct Service receiving a connection error. |
| 566 for (const auto& instance : instances_) |
| 567 instance.first->Stop(); |
| 568 service_manager_instance->Stop(); |
| 569 |
| 570 instances_.clear(); |
| 575 } | 571 } |
| 576 | 572 |
| 577 void ServiceManager::SetServiceOverrides( | 573 void ServiceManager::SetServiceOverrides( |
| 578 std::unique_ptr<ServiceOverrides> overrides) { | 574 std::unique_ptr<ServiceOverrides> overrides) { |
| 579 service_overrides_ = std::move(overrides); | 575 service_overrides_ = std::move(overrides); |
| 580 } | 576 } |
| 581 | 577 |
| 582 void ServiceManager::SetInstanceQuitCallback( | 578 void ServiceManager::SetInstanceQuitCallback( |
| 583 base::Callback<void(const Identity&)> callback) { | 579 base::Callback<void(const Identity&)> callback) { |
| 584 instance_quit_callback_ = callback; | 580 instance_quit_callback_ = callback; |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 635 identity_to_resolver_[identity] = std::move(resolver_ptr); | 631 identity_to_resolver_[identity] = std::move(resolver_ptr); |
| 636 return resolver; | 632 return resolver; |
| 637 } | 633 } |
| 638 | 634 |
| 639 void ServiceManager::OnInstanceError(Instance* instance) { | 635 void ServiceManager::OnInstanceError(Instance* instance) { |
| 640 // We never clean up the ServiceManager's own instance. | 636 // We never clean up the ServiceManager's own instance. |
| 641 if (instance == service_manager_instance_) | 637 if (instance == service_manager_instance_) |
| 642 return; | 638 return; |
| 643 | 639 |
| 644 EraseInstanceIdentity(instance); | 640 EraseInstanceIdentity(instance); |
| 645 if (instance->parent()) { | 641 auto it = instances_.find(instance); |
| 646 // Deletes |instance|. | 642 DCHECK(it != instances_.end()); |
| 647 instance->parent()->RemoveChild(instance); | |
| 648 } else { | |
| 649 auto it = root_instances_.find(instance); | |
| 650 DCHECK(it != root_instances_.end()); | |
| 651 | 643 |
| 652 // Deletes |instance|. | 644 // Deletes |instance|. |
| 653 root_instances_.erase(it); | 645 instances_.erase(it); |
| 654 } | |
| 655 } | 646 } |
| 656 | 647 |
| 657 void ServiceManager::OnInstanceUnreachable(Instance* instance) { | 648 void ServiceManager::OnInstanceUnreachable(Instance* instance) { |
| 658 // If an Instance becomes unreachable, new connection requests for this | 649 // If an Instance becomes unreachable, new connection requests for this |
| 659 // identity will elicit a new Instance instantiation. The unreachable instance | 650 // identity will elicit a new Instance instantiation. The unreachable instance |
| 660 // remains alive. | 651 // remains alive. |
| 661 EraseInstanceIdentity(instance); | 652 EraseInstanceIdentity(instance); |
| 662 } | 653 } |
| 663 | 654 |
| 664 void ServiceManager::OnInstanceStopped(const Identity& identity) { | 655 void ServiceManager::OnInstanceStopped(const Identity& identity) { |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 762 | 753 |
| 763 ServiceManager::Instance* ServiceManager::CreateInstance( | 754 ServiceManager::Instance* ServiceManager::CreateInstance( |
| 764 const Identity& source, | 755 const Identity& source, |
| 765 const Identity& target, | 756 const Identity& target, |
| 766 const InterfaceProviderSpecMap& specs) { | 757 const InterfaceProviderSpecMap& specs) { |
| 767 CHECK(target.user_id() != mojom::kInheritUserID); | 758 CHECK(target.user_id() != mojom::kInheritUserID); |
| 768 | 759 |
| 769 auto instance = base::MakeUnique<Instance>(this, target, specs); | 760 auto instance = base::MakeUnique<Instance>(this, target, specs); |
| 770 Instance* raw_instance = instance.get(); | 761 Instance* raw_instance = instance.get(); |
| 771 | 762 |
| 772 Instance* source_instance = GetExistingInstance(source); | 763 instances_.insert(std::make_pair(raw_instance, std::move(instance))); |
| 773 if (source_instance) | |
| 774 source_instance->AddChild(std::move(instance)); | |
| 775 else | |
| 776 root_instances_.insert(std::make_pair(raw_instance, std::move(instance))); | |
| 777 | 764 |
| 778 // NOTE: |instance| has been passed elsewhere. Use |raw_instance| from this | 765 // NOTE: |instance| has been passed elsewhere. Use |raw_instance| from this |
| 779 // point forward. It's safe for the extent of this method. | 766 // point forward. It's safe for the extent of this method. |
| 780 | 767 |
| 781 auto result = | 768 auto result = |
| 782 identity_to_instance_.insert(std::make_pair(target, raw_instance)); | 769 identity_to_instance_.insert(std::make_pair(target, raw_instance)); |
| 783 DCHECK(result.second); | 770 DCHECK(result.second); |
| 784 | 771 |
| 785 mojom::RunningServiceInfoPtr info = raw_instance->CreateRunningServiceInfo(); | 772 mojom::RunningServiceInfoPtr info = raw_instance->CreateRunningServiceInfo(); |
| 786 listeners_.ForAllPtrs([&info](mojom::ServiceManagerListener* listener) { | 773 listeners_.ForAllPtrs([&info](mojom::ServiceManagerListener* listener) { |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 961 // Now that the instance has a Service, we can connect to it. | 948 // Now that the instance has a Service, we can connect to it. |
| 962 bool connected = instance->ConnectToService(¶ms); | 949 bool connected = instance->ConnectToService(¶ms); |
| 963 DCHECK(connected); | 950 DCHECK(connected); |
| 964 } | 951 } |
| 965 | 952 |
| 966 base::WeakPtr<ServiceManager> ServiceManager::GetWeakPtr() { | 953 base::WeakPtr<ServiceManager> ServiceManager::GetWeakPtr() { |
| 967 return weak_ptr_factory_.GetWeakPtr(); | 954 return weak_ptr_factory_.GetWeakPtr(); |
| 968 } | 955 } |
| 969 | 956 |
| 970 } // namespace service_manager | 957 } // namespace service_manager |
| OLD | NEW |