| Index: services/service_manager/public/cpp/lib/service_context.cc
|
| diff --git a/services/service_manager/public/cpp/lib/service_context.cc b/services/service_manager/public/cpp/lib/service_context.cc
|
| index a3b8f7d614aba2d3ff51c712512f02d9cebf3184..5a767b066a25aa0d3b9cba70ed5c892d18c2ddcb 100644
|
| --- a/services/service_manager/public/cpp/lib/service_context.cc
|
| +++ b/services/service_manager/public/cpp/lib/service_context.cc
|
| @@ -4,6 +4,8 @@
|
|
|
| #include "services/service_manager/public/cpp/service_context.h"
|
|
|
| +#include <utility>
|
| +
|
| #include "base/bind.h"
|
| #include "base/logging.h"
|
| #include "base/message_loop/message_loop.h"
|
| @@ -26,7 +28,8 @@ ServiceContext::ServiceContext(service_manager::Service* service,
|
| : pending_connector_request_(std::move(connector_request)),
|
| service_(service),
|
| binding_(this, std::move(request)),
|
| - connector_(std::move(connector)) {
|
| + connector_(std::move(connector)),
|
| + weak_factory_(this) {
|
| DCHECK(binding_.is_bound());
|
| binding_.set_connection_error_handler(
|
| base::Bind(&ServiceContext::OnConnectionError, base::Unretained(this)));
|
| @@ -76,9 +79,12 @@ void ServiceContext::OnConnect(
|
| if (!service_->OnConnect(source_info, registry.get()))
|
| return;
|
|
|
| - // TODO(beng): it appears we never prune this list. We should, when the
|
| - // registry's remote interface provider pipe breaks.
|
| - incoming_connections_.push_back(std::move(registry));
|
| + InterfaceRegistry* raw_registry = registry.get();
|
| + registry->AddConnectionLostClosure(base::Bind(
|
| + &ServiceContext::OnRegistryConnectionError, base::Unretained(this),
|
| + raw_registry));
|
| + connection_interface_registries_.insert(
|
| + std::make_pair(raw_registry, std::move(registry)));
|
| }
|
|
|
| ////////////////////////////////////////////////////////////////////////////////
|
| @@ -96,4 +102,21 @@ void ServiceContext::OnConnectionError() {
|
| // Connect() will return nullptr if they try to connect to anything.
|
| }
|
|
|
| +void ServiceContext::OnRegistryConnectionError(InterfaceRegistry* registry) {
|
| + // NOTE: We destroy the InterfaceRegistry asynchronously since it's calling
|
| + // into us from its own connection error handler which may continue to access
|
| + // the InterfaceRegistry's own state after we return.
|
| + base::ThreadTaskRunnerHandle::Get()->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&ServiceContext::DestroyConnectionInterfaceRegistry,
|
| + weak_factory_.GetWeakPtr(), registry));
|
| +}
|
| +
|
| +void ServiceContext::DestroyConnectionInterfaceRegistry(
|
| + InterfaceRegistry* registry) {
|
| + auto it = connection_interface_registries_.find(registry);
|
| + CHECK(it != connection_interface_registries_.end());
|
| + connection_interface_registries_.erase(it);
|
| +}
|
| +
|
| } // namespace service_manager
|
|
|