blob: e29e94c025697b64fe39fa047f46c660ed0fc749 [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
dgn3563ecaf2016-03-09 19:28:2629bool KeepAliveRegistry::IsRestartAllowed() const {
30 return registered_count_ == restart_allowed_count_;
31}
32
dgnfe075c82016-03-18 11:25:3533bool KeepAliveRegistry::IsOriginRegistered(KeepAliveOrigin origin) const {
34 return registered_keep_alives_.find(origin) != registered_keep_alives_.end();
35}
36
dgn3563ecaf2016-03-09 19:28:2637void KeepAliveRegistry::AddObserver(KeepAliveStateObserver* observer) {
38 observers_.AddObserver(observer);
39}
40
41void KeepAliveRegistry::RemoveObserver(KeepAliveStateObserver* observer) {
42 observers_.RemoveObserver(observer);
43}
44
dgnaf6e8612016-08-12 12:24:0945bool KeepAliveRegistry::WouldRestartWithout(
46 const std::vector<KeepAliveOrigin>& origins) const {
47 int registered_count = 0;
48 int restart_allowed_count = 0;
49
50 for (auto origin : origins) {
51 auto counts_it = registered_keep_alives_.find(origin);
52 if (counts_it != registered_keep_alives_.end()) {
53 registered_count += counts_it->second;
54
55 counts_it = restart_allowed_keep_alives_.find(origin);
56 if (counts_it != restart_allowed_keep_alives_.end())
57 restart_allowed_count += counts_it->second;
58 } else {
59 // |registered_keep_alives_| is supposed to be a superset of
60 // |restart_allowed_keep_alives_|
61 DCHECK(restart_allowed_keep_alives_.find(origin) ==
62 restart_allowed_keep_alives_.end());
63 }
64 }
65
66 registered_count = registered_count_ - registered_count;
67 restart_allowed_count = restart_allowed_count_ - restart_allowed_count;
68
69 DCHECK_GE(registered_count, 0);
70 DCHECK_GE(restart_allowed_count, 0);
71
72 return registered_count == restart_allowed_count;
73}
74
Michael Giuffrida2dbce0d12017-09-02 03:30:5975void KeepAliveRegistry::SetIsShuttingDown(bool value) {
76#if DCHECK_IS_ON()
77 is_shutting_down_ = value;
78#endif
79}
80
dgn3d351ad12016-02-26 17:36:4581////////////////////////////////////////////////////////////////////////////////
82// Private methods
83
dgn3563ecaf2016-03-09 19:28:2684KeepAliveRegistry::KeepAliveRegistry()
85 : registered_count_(0), restart_allowed_count_(0) {}
dgn3d351ad12016-02-26 17:36:4586
87KeepAliveRegistry::~KeepAliveRegistry() {
dgn02377782016-03-12 00:58:3888 DLOG_IF(ERROR, registered_count_ > 0 || registered_keep_alives_.size() > 0)
dgn1e50dd22016-04-22 22:16:5689 << "KeepAliveRegistry not empty at destruction time. State:" << *this;
dgn3d351ad12016-02-26 17:36:4590}
91
dgn3563ecaf2016-03-09 19:28:2692void KeepAliveRegistry::Register(KeepAliveOrigin origin,
93 KeepAliveRestartOption restart) {
Michael Giuffrida2dbce0d12017-09-02 03:30:5994#if DCHECK_IS_ON()
95 DCHECK(!is_shutting_down_);
96#endif
dgn1e50dd22016-04-22 22:16:5697
dgn3563ecaf2016-03-09 19:28:2698 bool old_keeping_alive = IsKeepingAlive();
99 bool old_restart_allowed = IsRestartAllowed();
dgn3d351ad12016-02-26 17:36:45100
101 ++registered_keep_alives_[origin];
102 ++registered_count_;
dgn3563ecaf2016-03-09 19:28:26103
dgnaf6e8612016-08-12 12:24:09104 if (restart == KeepAliveRestartOption::ENABLED) {
105 ++restart_allowed_keep_alives_[origin];
dgn3563ecaf2016-03-09 19:28:26106 ++restart_allowed_count_;
dgnaf6e8612016-08-12 12:24:09107 }
dgn3563ecaf2016-03-09 19:28:26108
109 bool new_keeping_alive = IsKeepingAlive();
110 bool new_restart_allowed = IsRestartAllowed();
111
112 if (new_keeping_alive != old_keeping_alive)
dgnfe075c82016-03-18 11:25:35113 OnKeepAliveStateChanged(new_keeping_alive);
dgn3563ecaf2016-03-09 19:28:26114
115 if (new_restart_allowed != old_restart_allowed)
116 OnRestartAllowedChanged(new_restart_allowed);
117
dgn1e50dd22016-04-22 22:16:56118 DVLOG(1) << "New state of the KeepAliveRegistry: " << *this;
dgn3d351ad12016-02-26 17:36:45119}
120
dgn3563ecaf2016-03-09 19:28:26121void KeepAliveRegistry::Unregister(KeepAliveOrigin origin,
122 KeepAliveRestartOption restart) {
123 bool old_keeping_alive = IsKeepingAlive();
124 bool old_restart_allowed = IsRestartAllowed();
125
dgn3d351ad12016-02-26 17:36:45126 --registered_count_;
127 DCHECK_GE(registered_count_, 0);
dgnaf6e8612016-08-12 12:24:09128 DecrementCount(origin, &registered_keep_alives_);
dgn3d351ad12016-02-26 17:36:45129
dgnaf6e8612016-08-12 12:24:09130 if (restart == KeepAliveRestartOption::ENABLED) {
dgn3563ecaf2016-03-09 19:28:26131 --restart_allowed_count_;
dgnaf6e8612016-08-12 12:24:09132 DecrementCount(origin, &restart_allowed_keep_alives_);
133 }
dgn3563ecaf2016-03-09 19:28:26134
135 bool new_keeping_alive = IsKeepingAlive();
136 bool new_restart_allowed = IsRestartAllowed();
137
dgn3eaf67e2016-07-26 09:01:12138 // Update the KeepAlive state first, so that listeners can check if we are
139 // trying to shutdown.
dgn3563ecaf2016-03-09 19:28:26140 if (new_keeping_alive != old_keeping_alive)
dgnfe075c82016-03-18 11:25:35141 OnKeepAliveStateChanged(new_keeping_alive);
dgn3563ecaf2016-03-09 19:28:26142
dgn3eaf67e2016-07-26 09:01:12143 if (new_restart_allowed != old_restart_allowed)
144 OnRestartAllowedChanged(new_restart_allowed);
145
dgn1e50dd22016-04-22 22:16:56146 DVLOG(1) << "New state of the KeepAliveRegistry:" << *this;
dgn3d351ad12016-02-26 17:36:45147}
dgn3563ecaf2016-03-09 19:28:26148
dgnfe075c82016-03-18 11:25:35149void KeepAliveRegistry::OnKeepAliveStateChanged(bool new_keeping_alive) {
150 DVLOG(1) << "Notifying KeepAliveStateObservers: KeepingAlive changed to: "
151 << new_keeping_alive;
manzagopba8991e2017-05-08 21:05:21152#if defined(OS_WIN)
153 browser_watcher::SetStabilityDataBool(browser_watcher::kStabilityKeepAlive,
154 new_keeping_alive);
155#endif
ericwilligers58b0e162016-10-21 07:15:56156 for (KeepAliveStateObserver& observer : observers_)
157 observer.OnKeepAliveStateChanged(new_keeping_alive);
dgn3563ecaf2016-03-09 19:28:26158}
159
160void KeepAliveRegistry::OnRestartAllowedChanged(bool new_restart_allowed) {
161 DVLOG(1) << "Notifying KeepAliveStateObservers: Restart changed to: "
162 << new_restart_allowed;
manzagopba8991e2017-05-08 21:05:21163#if defined(OS_WIN)
164 browser_watcher::SetStabilityDataBool(
165 browser_watcher::kStabilityRestartAllowed, new_restart_allowed);
166#endif
ericwilligers58b0e162016-10-21 07:15:56167 for (KeepAliveStateObserver& observer : observers_)
168 observer.OnKeepAliveRestartStateChanged(new_restart_allowed);
dgn3563ecaf2016-03-09 19:28:26169}
170
dgnaf6e8612016-08-12 12:24:09171void KeepAliveRegistry::DecrementCount(KeepAliveOrigin origin,
172 OriginMap* keep_alive_map) {
173 int new_count = --keep_alive_map->at(origin);
174 DCHECK_GE(keep_alive_map->at(origin), 0);
175 if (new_count == 0)
176 keep_alive_map->erase(origin);
177}
178
dgn3563ecaf2016-03-09 19:28:26179std::ostream& operator<<(std::ostream& out, const KeepAliveRegistry& registry) {
dgn02377782016-03-12 00:58:38180 out << "{registered_count_=" << registry.registered_count_
181 << ", restart_allowed_count_=" << registry.restart_allowed_count_
182 << ", KeepAlives=[";
dgn3563ecaf2016-03-09 19:28:26183 for (auto counts_per_origin_it : registry.registered_keep_alives_) {
184 if (counts_per_origin_it != *registry.registered_keep_alives_.begin())
185 out << ", ";
186 out << counts_per_origin_it.first << " (" << counts_per_origin_it.second
187 << ")";
188 }
189 out << "]}";
190 return out;
191}