blob: 053699b74c3181d9490a234cb190deef4a4bcb82 [file] [log] [blame]
dgn3d351ad12016-02-26 17:36:451// Copyright 2016 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Michael Giuffrida2dbce0d12017-09-02 03:30:595#include "components/keep_alive_registry/keep_alive_registry.h"
dgn3d351ad12016-02-26 17:36:456
Michael Giuffrida2dbce0d12017-09-02 03:30:597#include "base/logging.h"
manzagopba8991e2017-05-08 21:05:218#include "build/build_config.h"
Michael Giuffrida2dbce0d12017-09-02 03:30:599#include "components/keep_alive_registry/keep_alive_state_observer.h"
10#include "components/keep_alive_registry/keep_alive_types.h"
dgn3d351ad12016-02-26 17:36:4511
manzagopba8991e2017-05-08 21:05:2112#if defined(OS_WIN)
13#include "components/browser_watcher/stability_data_names.h"
14#include "components/browser_watcher/stability_debugging.h"
15#endif
16
dgn3d351ad12016-02-26 17:36:4517////////////////////////////////////////////////////////////////////////////////
18// Public methods
19
20// static
21KeepAliveRegistry* KeepAliveRegistry::GetInstance() {
22 return base::Singleton<KeepAliveRegistry>::get();
23}
24
dgn3563ecaf2016-03-09 19:28:2625bool KeepAliveRegistry::IsKeepingAlive() const {
dgn3d351ad12016-02-26 17:36:4526 return registered_count_ > 0;
27}
28
Aleksei Seren121533e2017-11-28 20:11:1829bool KeepAliveRegistry::IsKeepingAliveOnlyByBrowserOrigin() const {
30 for (const auto& value : registered_keep_alives_) {
31 if (value.first != KeepAliveOrigin::BROWSER)
32 return false;
33 }
34 return true;
35}
36
dgn3563ecaf2016-03-09 19:28:2637bool KeepAliveRegistry::IsRestartAllowed() const {
38 return registered_count_ == restart_allowed_count_;
39}
40
dgnfe075c82016-03-18 11:25:3541bool KeepAliveRegistry::IsOriginRegistered(KeepAliveOrigin origin) const {
42 return registered_keep_alives_.find(origin) != registered_keep_alives_.end();
43}
44
dgn3563ecaf2016-03-09 19:28:2645void KeepAliveRegistry::AddObserver(KeepAliveStateObserver* observer) {
46 observers_.AddObserver(observer);
47}
48
49void KeepAliveRegistry::RemoveObserver(KeepAliveStateObserver* observer) {
50 observers_.RemoveObserver(observer);
51}
52
dgnaf6e8612016-08-12 12:24:0953bool KeepAliveRegistry::WouldRestartWithout(
54 const std::vector<KeepAliveOrigin>& origins) const {
55 int registered_count = 0;
56 int restart_allowed_count = 0;
57
58 for (auto origin : origins) {
59 auto counts_it = registered_keep_alives_.find(origin);
60 if (counts_it != registered_keep_alives_.end()) {
61 registered_count += counts_it->second;
62
63 counts_it = restart_allowed_keep_alives_.find(origin);
64 if (counts_it != restart_allowed_keep_alives_.end())
65 restart_allowed_count += counts_it->second;
66 } else {
67 // |registered_keep_alives_| is supposed to be a superset of
68 // |restart_allowed_keep_alives_|
69 DCHECK(restart_allowed_keep_alives_.find(origin) ==
70 restart_allowed_keep_alives_.end());
71 }
72 }
73
74 registered_count = registered_count_ - registered_count;
75 restart_allowed_count = restart_allowed_count_ - restart_allowed_count;
76
77 DCHECK_GE(registered_count, 0);
78 DCHECK_GE(restart_allowed_count, 0);
79
80 return registered_count == restart_allowed_count;
81}
82
Michael Giuffrida2dbce0d12017-09-02 03:30:5983void KeepAliveRegistry::SetIsShuttingDown(bool value) {
Michael Giuffrida2dbce0d12017-09-02 03:30:5984 is_shutting_down_ = value;
Michael Giuffrida2dbce0d12017-09-02 03:30:5985}
86
dgn3d351ad12016-02-26 17:36:4587////////////////////////////////////////////////////////////////////////////////
88// Private methods
89
dgn3563ecaf2016-03-09 19:28:2690KeepAliveRegistry::KeepAliveRegistry()
91 : registered_count_(0), restart_allowed_count_(0) {}
dgn3d351ad12016-02-26 17:36:4592
93KeepAliveRegistry::~KeepAliveRegistry() {
Wez2f88261b2018-04-16 18:03:0994 DCHECK_LE(registered_count_, 0) << "KeepAliveRegistry state:" << *this;
95 DCHECK_EQ(registered_keep_alives_.size(), 0u)
96 << "KeepAliveRegistry state:" << *this;
dgn3d351ad12016-02-26 17:36:4597}
98
dgn3563ecaf2016-03-09 19:28:2699void KeepAliveRegistry::Register(KeepAliveOrigin origin,
100 KeepAliveRestartOption restart) {
Wez2f88261b2018-04-16 18:03:09101 CHECK(!is_shutting_down_);
dgn1e50dd22016-04-22 22:16:56102
dgn3563ecaf2016-03-09 19:28:26103 bool old_keeping_alive = IsKeepingAlive();
104 bool old_restart_allowed = IsRestartAllowed();
dgn3d351ad12016-02-26 17:36:45105
106 ++registered_keep_alives_[origin];
107 ++registered_count_;
dgn3563ecaf2016-03-09 19:28:26108
dgnaf6e8612016-08-12 12:24:09109 if (restart == KeepAliveRestartOption::ENABLED) {
110 ++restart_allowed_keep_alives_[origin];
dgn3563ecaf2016-03-09 19:28:26111 ++restart_allowed_count_;
dgnaf6e8612016-08-12 12:24:09112 }
dgn3563ecaf2016-03-09 19:28:26113
114 bool new_keeping_alive = IsKeepingAlive();
115 bool new_restart_allowed = IsRestartAllowed();
116
117 if (new_keeping_alive != old_keeping_alive)
dgnfe075c82016-03-18 11:25:35118 OnKeepAliveStateChanged(new_keeping_alive);
dgn3563ecaf2016-03-09 19:28:26119
120 if (new_restart_allowed != old_restart_allowed)
121 OnRestartAllowedChanged(new_restart_allowed);
122
dgn1e50dd22016-04-22 22:16:56123 DVLOG(1) << "New state of the KeepAliveRegistry: " << *this;
dgn3d351ad12016-02-26 17:36:45124}
125
dgn3563ecaf2016-03-09 19:28:26126void KeepAliveRegistry::Unregister(KeepAliveOrigin origin,
127 KeepAliveRestartOption restart) {
128 bool old_keeping_alive = IsKeepingAlive();
129 bool old_restart_allowed = IsRestartAllowed();
130
dgn3d351ad12016-02-26 17:36:45131 --registered_count_;
132 DCHECK_GE(registered_count_, 0);
dgnaf6e8612016-08-12 12:24:09133 DecrementCount(origin, &registered_keep_alives_);
dgn3d351ad12016-02-26 17:36:45134
dgnaf6e8612016-08-12 12:24:09135 if (restart == KeepAliveRestartOption::ENABLED) {
dgn3563ecaf2016-03-09 19:28:26136 --restart_allowed_count_;
dgnaf6e8612016-08-12 12:24:09137 DecrementCount(origin, &restart_allowed_keep_alives_);
138 }
dgn3563ecaf2016-03-09 19:28:26139
140 bool new_keeping_alive = IsKeepingAlive();
141 bool new_restart_allowed = IsRestartAllowed();
142
dgn3eaf67e2016-07-26 09:01:12143 // Update the KeepAlive state first, so that listeners can check if we are
144 // trying to shutdown.
dgn3563ecaf2016-03-09 19:28:26145 if (new_keeping_alive != old_keeping_alive)
dgnfe075c82016-03-18 11:25:35146 OnKeepAliveStateChanged(new_keeping_alive);
dgn3563ecaf2016-03-09 19:28:26147
dgn3eaf67e2016-07-26 09:01:12148 if (new_restart_allowed != old_restart_allowed)
149 OnRestartAllowedChanged(new_restart_allowed);
150
dgn1e50dd22016-04-22 22:16:56151 DVLOG(1) << "New state of the KeepAliveRegistry:" << *this;
dgn3d351ad12016-02-26 17:36:45152}
dgn3563ecaf2016-03-09 19:28:26153
dgnfe075c82016-03-18 11:25:35154void KeepAliveRegistry::OnKeepAliveStateChanged(bool new_keeping_alive) {
155 DVLOG(1) << "Notifying KeepAliveStateObservers: KeepingAlive changed to: "
156 << new_keeping_alive;
manzagopba8991e2017-05-08 21:05:21157#if defined(OS_WIN)
158 browser_watcher::SetStabilityDataBool(browser_watcher::kStabilityKeepAlive,
159 new_keeping_alive);
160#endif
ericwilligers58b0e162016-10-21 07:15:56161 for (KeepAliveStateObserver& observer : observers_)
162 observer.OnKeepAliveStateChanged(new_keeping_alive);
dgn3563ecaf2016-03-09 19:28:26163}
164
165void KeepAliveRegistry::OnRestartAllowedChanged(bool new_restart_allowed) {
166 DVLOG(1) << "Notifying KeepAliveStateObservers: Restart changed to: "
167 << new_restart_allowed;
manzagopba8991e2017-05-08 21:05:21168#if defined(OS_WIN)
169 browser_watcher::SetStabilityDataBool(
170 browser_watcher::kStabilityRestartAllowed, new_restart_allowed);
171#endif
ericwilligers58b0e162016-10-21 07:15:56172 for (KeepAliveStateObserver& observer : observers_)
173 observer.OnKeepAliveRestartStateChanged(new_restart_allowed);
dgn3563ecaf2016-03-09 19:28:26174}
175
dgnaf6e8612016-08-12 12:24:09176void KeepAliveRegistry::DecrementCount(KeepAliveOrigin origin,
177 OriginMap* keep_alive_map) {
178 int new_count = --keep_alive_map->at(origin);
179 DCHECK_GE(keep_alive_map->at(origin), 0);
180 if (new_count == 0)
181 keep_alive_map->erase(origin);
182}
183
dgn3563ecaf2016-03-09 19:28:26184std::ostream& operator<<(std::ostream& out, const KeepAliveRegistry& registry) {
dgn02377782016-03-12 00:58:38185 out << "{registered_count_=" << registry.registered_count_
186 << ", restart_allowed_count_=" << registry.restart_allowed_count_
187 << ", KeepAlives=[";
dgn3563ecaf2016-03-09 19:28:26188 for (auto counts_per_origin_it : registry.registered_keep_alives_) {
189 if (counts_per_origin_it != *registry.registered_keep_alives_.begin())
190 out << ", ";
191 out << counts_per_origin_it.first << " (" << counts_per_origin_it.second
192 << ")";
193 }
194 out << "]}";
195 return out;
196}