| // Copyright 2018 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "services/service_manager/public/cpp/service_keepalive.h" |
| |
| #include "base/bind.h" |
| #include "base/task_scheduler/post_task.h" |
| #include "services/service_manager/public/cpp/service_context.h" |
| |
| namespace service_manager { |
| |
| ServiceKeepalive::ServiceKeepalive(ServiceContext* context, |
| base::TimeDelta idle_timeout, |
| TimeoutObserver* timeout_observer) |
| : context_(context), |
| idle_timeout_(idle_timeout), |
| timeout_observer_(timeout_observer), |
| ref_factory_(base::BindRepeating(&ServiceKeepalive::OnRefCountZero, |
| base::Unretained(this))), |
| weak_ptr_factory_(this) { |
| ref_factory_.SetRefAddedCallback(base::BindRepeating( |
| &ServiceKeepalive::OnRefAdded, base::Unretained(this))); |
| } |
| |
| ServiceKeepalive::~ServiceKeepalive() = default; |
| |
| std::unique_ptr<ServiceContextRef> ServiceKeepalive::CreateRef() { |
| return ref_factory_.CreateRef(); |
| } |
| |
| bool ServiceKeepalive::HasNoRefs() { |
| return ref_factory_.HasNoRefs(); |
| } |
| |
| void ServiceKeepalive::OnRefAdded() { |
| if (idle_timer_.IsRunning() && timeout_observer_) |
| timeout_observer_->OnTimeoutCancelled(); |
| idle_timer_.Stop(); |
| } |
| |
| void ServiceKeepalive::OnRefCountZero() { |
| idle_timer_.Start(FROM_HERE, idle_timeout_, |
| base::BindRepeating(&ServiceKeepalive::OnTimerExpired, |
| weak_ptr_factory_.GetWeakPtr())); |
| } |
| |
| void ServiceKeepalive::OnTimerExpired() { |
| if (timeout_observer_) |
| timeout_observer_->OnTimeoutExpired(); |
| context_->CreateQuitClosure().Run(); |
| } |
| |
| } // namespace service_manager |