Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(283)

Side by Side Diff: services/service_manager/service_manager.cc

Issue 2480603004: Service Manager: Implement graceful service termination (Closed)
Patch Set: Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/command_line.h" 12 #include "base/command_line.h"
13 #include "base/debug/alias.h" 13 #include "base/debug/alias.h"
14 #include "base/guid.h" 14 #include "base/guid.h"
15 #include "base/logging.h" 15 #include "base/logging.h"
16 #include "base/macros.h" 16 #include "base/macros.h"
17 #include "base/process/process.h" 17 #include "base/process/process.h"
18 #include "base/process/process_handle.h" 18 #include "base/process/process_handle.h"
19 #include "base/stl_util.h" 19 #include "base/stl_util.h"
20 #include "base/strings/string_util.h" 20 #include "base/strings/string_util.h"
21 #include "base/trace_event/trace_event.h" 21 #include "base/trace_event/trace_event.h"
22 #include "mojo/public/cpp/bindings/associated_binding.h"
22 #include "mojo/public/cpp/bindings/binding.h" 23 #include "mojo/public/cpp/bindings/binding.h"
23 #include "mojo/public/cpp/bindings/binding_set.h" 24 #include "mojo/public/cpp/bindings/binding_set.h"
24 #include "services/service_manager/connect_util.h" 25 #include "services/service_manager/connect_util.h"
25 #include "services/service_manager/public/cpp/connector.h" 26 #include "services/service_manager/public/cpp/connector.h"
26 #include "services/service_manager/public/cpp/interface_registry.h" 27 #include "services/service_manager/public/cpp/interface_registry.h"
27 #include "services/service_manager/public/cpp/names.h" 28 #include "services/service_manager/public/cpp/names.h"
28 #include "services/service_manager/public/cpp/service.h" 29 #include "services/service_manager/public/cpp/service.h"
29 #include "services/service_manager/public/cpp/service_context.h" 30 #include "services/service_manager/public/cpp/service_context.h"
30 #include "services/service_manager/public/interfaces/connector.mojom.h" 31 #include "services/service_manager/public/interfaces/connector.mojom.h"
31 #include "services/service_manager/public/interfaces/service.mojom.h" 32 #include "services/service_manager/public/interfaces/service.mojom.h"
33 #include "services/service_manager/public/interfaces/service_control.mojom.h"
32 #include "services/service_manager/public/interfaces/service_manager.mojom.h" 34 #include "services/service_manager/public/interfaces/service_manager.mojom.h"
33 35
34 namespace service_manager { 36 namespace service_manager {
35 37
36 namespace { 38 namespace {
37 39
38 const char kCatalogName[] = "service:catalog"; 40 const char kCatalogName[] = "service:catalog";
39 const char kServiceManagerName[] = "service:service_manager"; 41 const char kServiceManagerName[] = "service:service_manager";
40 const char kCapability_UserID[] = "service_manager:user_id"; 42 const char kCapability_UserID[] = "service_manager:user_id";
41 const char kCapability_ClientProcess[] = "service_manager:client_process"; 43 const char kCapability_ClientProcess[] = "service_manager:client_process";
(...skipping 29 matching lines...) Expand all
71 return it->second.find(capability) != it->second.end(); 73 return it->second.find(capability) != it->second.end();
72 } 74 }
73 75
74 // Encapsulates a connection to an instance of a service, tracked by the 76 // Encapsulates a connection to an instance of a service, tracked by the
75 // Service Manager. 77 // Service Manager.
76 class ServiceManager::Instance 78 class ServiceManager::Instance
77 : public mojom::Connector, 79 : public mojom::Connector,
78 public mojom::PIDReceiver, 80 public mojom::PIDReceiver,
79 public Service, 81 public Service,
80 public InterfaceFactory<mojom::ServiceManager>, 82 public InterfaceFactory<mojom::ServiceManager>,
81 public mojom::ServiceManager { 83 public mojom::ServiceManager,
84 public mojom::ServiceControl {
82 public: 85 public:
83 Instance(service_manager::ServiceManager* service_manager, 86 Instance(service_manager::ServiceManager* service_manager,
84 const Identity& identity, 87 const Identity& identity,
85 const InterfaceProviderSpecMap& interface_provider_specs) 88 const InterfaceProviderSpecMap& interface_provider_specs)
86 : service_manager_(service_manager), 89 : service_manager_(service_manager),
87 id_(GenerateUniqueID()), 90 id_(GenerateUniqueID()),
88 identity_(identity), 91 identity_(identity),
89 interface_provider_specs_(interface_provider_specs), 92 interface_provider_specs_(interface_provider_specs),
90 allow_any_application_(GetConnectionSpec().requires.count("*") == 1), 93 allow_any_application_(GetConnectionSpec().requires.count("*") == 1),
91 pid_receiver_binding_(this), 94 pid_receiver_binding_(this),
95 control_binding_(this),
92 state_(State::IDLE), 96 state_(State::IDLE),
93 weak_factory_(this) { 97 weak_factory_(this) {
94 if (identity_.name() == kServiceManagerName || 98 if (identity_.name() == kServiceManagerName ||
95 identity_.name() == kCatalogName) { 99 identity_.name() == kCatalogName) {
96 pid_ = base::Process::Current().Pid(); 100 pid_ = base::Process::Current().Pid();
97 } 101 }
98 DCHECK_NE(mojom::kInvalidInstanceID, id_); 102 DCHECK_NE(mojom::kInvalidInstanceID, id_);
99 } 103 }
100 104
101 ~Instance() override { 105 ~Instance() override {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 std::unique_ptr<ConnectParams> params(std::move(*connect_params)); 148 std::unique_ptr<ConnectParams> params(std::move(*connect_params));
145 if (!params->connect_callback().is_null()) { 149 if (!params->connect_callback().is_null()) {
146 params->connect_callback().Run(mojom::ConnectResult::SUCCEEDED, 150 params->connect_callback().Run(mojom::ConnectResult::SUCCEEDED,
147 identity_.user_id()); 151 identity_.user_id());
148 } 152 }
149 153
150 InterfaceProviderSpecMap specs; 154 InterfaceProviderSpecMap specs;
151 Instance* source = service_manager_->GetExistingInstance(params->source()); 155 Instance* source = service_manager_->GetExistingInstance(params->source());
152 if (source) 156 if (source)
153 specs = source->interface_provider_specs_; 157 specs = source->interface_provider_specs_;
158
159 pending_service_connections_++;
154 service_->OnConnect(ServiceInfo(params->source(), specs), 160 service_->OnConnect(ServiceInfo(params->source(), specs),
155 params->TakeRemoteInterfaces()); 161 params->TakeRemoteInterfaces(),
162 base::Bind(&Instance::OnConnectComplete,
163 base::Unretained(this)));
156 return true; 164 return true;
157 } 165 }
158 166
167 void OnConnectComplete() {
168 DCHECK_GT(pending_service_connections_, 0);
169 pending_service_connections_--;
170 }
171
159 void StartWithService(mojom::ServicePtr service) { 172 void StartWithService(mojom::ServicePtr service) {
160 CHECK(!service_); 173 CHECK(!service_);
161 state_ = State::STARTING; 174 state_ = State::STARTING;
162 service_ = std::move(service); 175 service_ = std::move(service);
163 service_.set_connection_error_handler( 176 service_.set_connection_error_handler(
164 base::Bind(&Instance::OnServiceLost, base::Unretained(this), 177 base::Bind(&Instance::OnServiceLost, base::Unretained(this),
165 service_manager_->GetWeakPtr())); 178 service_manager_->GetWeakPtr()));
166 service_->OnStart(ServiceInfo(identity_, interface_provider_specs_), 179 service_->OnStart(ServiceInfo(identity_, interface_provider_specs_),
167 base::Bind(&Instance::OnInitializeResponse, 180 base::Bind(&Instance::OnStartComplete,
168 base::Unretained(this))); 181 base::Unretained(this)));
169 } 182 }
170 183
171 void StartWithClientProcessConnection( 184 void StartWithClientProcessConnection(
172 mojom::ClientProcessConnectionPtr client_process_connection) { 185 mojom::ClientProcessConnectionPtr client_process_connection) {
173 mojom::ServicePtr service; 186 mojom::ServicePtr service;
174 service.Bind(mojom::ServicePtrInfo( 187 service.Bind(mojom::ServicePtrInfo(
175 std::move(client_process_connection->service), 0)); 188 std::move(client_process_connection->service), 0));
176 pid_receiver_binding_.Bind( 189 pid_receiver_binding_.Bind(
177 std::move(client_process_connection->pid_receiver_request)); 190 std::move(client_process_connection->pid_receiver_request));
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
404 // Any time a Connector is lost or we lose the Service connection, it 417 // Any time a Connector is lost or we lose the Service connection, it
405 // may have been the last pipe using this Instance. If so, clean up. 418 // may have been the last pipe using this Instance. If so, clean up.
406 if (service_manager && !service_) { 419 if (service_manager && !service_) {
407 if (connectors_.empty()) 420 if (connectors_.empty())
408 service_manager->OnInstanceError(this); 421 service_manager->OnInstanceError(this);
409 else 422 else
410 service_manager->OnInstanceUnreachable(this); 423 service_manager->OnInstanceUnreachable(this);
411 } 424 }
412 } 425 }
413 426
414 void OnInitializeResponse(mojom::ConnectorRequest connector_request) { 427 void OnStartComplete(mojom::ConnectorRequest connector_request,
428 mojom::ServiceControlAssociatedRequest control_request) {
415 state_ = State::STARTED; 429 state_ = State::STARTED;
416 if (connector_request.is_pending()) { 430 if (connector_request.is_pending()) {
417 connectors_.AddBinding(this, std::move(connector_request)); 431 connectors_.AddBinding(this, std::move(connector_request));
418 connectors_.set_connection_error_handler( 432 connectors_.set_connection_error_handler(
419 base::Bind(&Instance::OnConnectionLost, base::Unretained(this), 433 base::Bind(&Instance::OnConnectionLost, base::Unretained(this),
420 service_manager_->GetWeakPtr())); 434 service_manager_->GetWeakPtr()));
421 } 435 }
436 if (control_request.is_pending())
437 control_binding_.Bind(std::move(control_request));
422 service_manager_->NotifyServiceStarted(identity_, pid_); 438 service_manager_->NotifyServiceStarted(identity_, pid_);
423 } 439 }
424 440
425 // Callback when NativeRunner completes. 441 // Callback when NativeRunner completes.
426 void OnRunnerCompleted() { 442 void OnRunnerCompleted() {
427 if (!runner_.get()) 443 if (!runner_.get())
428 return; // We're in the destructor. 444 return; // We're in the destructor.
429 445
430 service_manager_->OnInstanceError(this); 446 service_manager_->OnInstanceError(this);
431 } 447 }
432 448
449 // mojom::ServiceControl:
450 void RequestQuit() override {
451 // If quit is requested, oblige when there are no pending OnConnects.
452 if (!pending_service_connections_)
blundell 2016/11/08 14:12:56 If there are pending service connections, should t
453 OnServiceLost(service_manager_->GetWeakPtr());
454 }
455
433 service_manager::ServiceManager* const service_manager_; 456 service_manager::ServiceManager* const service_manager_;
434 457
435 // An id that identifies this instance. Distinct from pid, as a single process 458 // An id that identifies this instance. Distinct from pid, as a single process
436 // may vend multiple application instances, and this object may exist before a 459 // may vend multiple application instances, and this object may exist before a
437 // process is launched. 460 // process is launched.
438 const uint32_t id_; 461 const uint32_t id_;
439 Identity identity_; 462 Identity identity_;
440 const InterfaceProviderSpecMap interface_provider_specs_; 463 const InterfaceProviderSpecMap interface_provider_specs_;
441 const InterfaceProviderSpec empty_spec_; 464 const InterfaceProviderSpec empty_spec_;
442 const bool allow_any_application_; 465 const bool allow_any_application_;
443 std::unique_ptr<NativeRunner> runner_; 466 std::unique_ptr<NativeRunner> runner_;
444 mojom::ServicePtr service_; 467 mojom::ServicePtr service_;
445 mojo::Binding<mojom::PIDReceiver> pid_receiver_binding_; 468 mojo::Binding<mojom::PIDReceiver> pid_receiver_binding_;
446 mojo::BindingSet<mojom::Connector> connectors_; 469 mojo::BindingSet<mojom::Connector> connectors_;
447 mojo::BindingSet<mojom::ServiceManager> service_manager_bindings_; 470 mojo::BindingSet<mojom::ServiceManager> service_manager_bindings_;
471 mojo::AssociatedBinding<mojom::ServiceControl> control_binding_;
448 base::ProcessId pid_ = base::kNullProcessId; 472 base::ProcessId pid_ = base::kNullProcessId;
449 Instance* parent_ = nullptr; 473 Instance* parent_ = nullptr;
450 InstanceMap children_; 474 InstanceMap children_;
451 State state_; 475 State state_;
476
477 // The number of outstanding OnConnect requests which are in flight.
478 int pending_service_connections_ = 0;
479
452 base::WeakPtrFactory<Instance> weak_factory_; 480 base::WeakPtrFactory<Instance> weak_factory_;
453 481
454 DISALLOW_COPY_AND_ASSIGN(Instance); 482 DISALLOW_COPY_AND_ASSIGN(Instance);
455 }; 483 };
456 484
457 class ServiceManager::ServiceImpl : public Service { 485 class ServiceManager::ServiceImpl : public Service {
458 public: 486 public:
459 explicit ServiceImpl(ServiceManager* service_manager) 487 explicit ServiceImpl(ServiceManager* service_manager)
460 : service_manager_(service_manager) {} 488 : service_manager_(service_manager) {}
461 ~ServiceImpl() override {} 489 ~ServiceImpl() override {}
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after
915 // Now that the instance has a Service, we can connect to it. 943 // Now that the instance has a Service, we can connect to it.
916 bool connected = instance->ConnectToService(&params); 944 bool connected = instance->ConnectToService(&params);
917 DCHECK(connected); 945 DCHECK(connected);
918 } 946 }
919 947
920 base::WeakPtr<ServiceManager> ServiceManager::GetWeakPtr() { 948 base::WeakPtr<ServiceManager> ServiceManager::GetWeakPtr() {
921 return weak_ptr_factory_.GetWeakPtr(); 949 return weak_ptr_factory_.GetWeakPtr();
922 } 950 }
923 951
924 } // namespace service_manager 952 } // namespace service_manager
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698