OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "base/threading/watchdog.h" | 5 #include "base/threading/watchdog.h" |
6 | 6 |
7 #include "base/compiler_specific.h" | 7 #include "base/compiler_specific.h" |
8 #include "base/lazy_instance.h" | |
9 #include "base/logging.h" | 8 #include "base/logging.h" |
10 #include "base/threading/platform_thread.h" | 9 #include "base/threading/platform_thread.h" |
11 | 10 |
12 namespace base { | 11 namespace base { |
13 | 12 |
14 namespace { | 13 namespace { |
15 | 14 |
16 // When the debugger breaks (when we alarm), all the other alarms that are | 15 // When the debugger breaks (when we alarm), all the other alarms that are |
17 // armed will expire (also alarm). To diminish this effect, we track any | 16 // armed will expire (also alarm). To diminish this effect, we track any |
18 // delay due to debugger breaks, and we *try* to adjust the effective start | 17 // delay due to debugger breaks, and we *try* to adjust the effective start |
19 // time of other alarms to step past the debugging break. | 18 // time of other alarms to step past the debugging break. |
20 // Without this safety net, any alarm will typically trigger a host of follow | 19 // Without this safety net, any alarm will typically trigger a host of follow |
21 // on alarms from callers that specify old times. | 20 // on alarms from callers that specify old times. |
22 | 21 |
23 struct StaticData { | 22 struct StaticData { |
24 // Lock for access of static data... | 23 // Lock for access of static data... |
25 Lock lock; | 24 Lock lock; |
26 | 25 |
27 // When did we last alarm and get stuck (for a while) in a debugger? | 26 // When did we last alarm and get stuck (for a while) in a debugger? |
28 TimeTicks last_debugged_alarm_time; | 27 TimeTicks last_debugged_alarm_time; |
29 | 28 |
30 // How long did we sit on a break in the debugger? | 29 // How long did we sit on a break in the debugger? |
31 TimeDelta last_debugged_alarm_delay; | 30 TimeDelta last_debugged_alarm_delay; |
32 }; | 31 }; |
33 | 32 |
34 LazyInstance<StaticData>::Leaky g_static_data = LAZY_INSTANCE_INITIALIZER; | 33 StaticData* GetStaticData() { |
| 34 static auto static_data = new StaticData(); |
| 35 return static_data; |
| 36 } |
35 | 37 |
36 } // namespace | 38 } // namespace |
37 | 39 |
38 // Start thread running in a Disarmed state. | 40 // Start thread running in a Disarmed state. |
39 Watchdog::Watchdog(const TimeDelta& duration, | 41 Watchdog::Watchdog(const TimeDelta& duration, |
40 const std::string& thread_watched_name, | 42 const std::string& thread_watched_name, |
41 bool enabled) | 43 bool enabled) |
42 : enabled_(enabled), | 44 : enabled_(enabled), |
43 lock_(), | 45 lock_(), |
44 condition_variable_(&lock_), | 46 condition_variable_(&lock_), |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 void Watchdog::Alarm() { | 114 void Watchdog::Alarm() { |
113 DVLOG(1) << "Watchdog alarmed for " << thread_watched_name_; | 115 DVLOG(1) << "Watchdog alarmed for " << thread_watched_name_; |
114 } | 116 } |
115 | 117 |
116 //------------------------------------------------------------------------------ | 118 //------------------------------------------------------------------------------ |
117 // Internal private methods that the watchdog thread uses. | 119 // Internal private methods that the watchdog thread uses. |
118 | 120 |
119 void Watchdog::ThreadDelegate::ThreadMain() { | 121 void Watchdog::ThreadDelegate::ThreadMain() { |
120 SetThreadName(); | 122 SetThreadName(); |
121 TimeDelta remaining_duration; | 123 TimeDelta remaining_duration; |
122 StaticData* static_data = g_static_data.Pointer(); | 124 StaticData* static_data = GetStaticData(); |
123 while (1) { | 125 while (1) { |
124 AutoLock lock(watchdog_->lock_); | 126 AutoLock lock(watchdog_->lock_); |
125 while (DISARMED == watchdog_->state_) | 127 while (DISARMED == watchdog_->state_) |
126 watchdog_->condition_variable_.Wait(); | 128 watchdog_->condition_variable_.Wait(); |
127 if (SHUTDOWN == watchdog_->state_) { | 129 if (SHUTDOWN == watchdog_->state_) { |
128 watchdog_->state_ = JOINABLE; | 130 watchdog_->state_ = JOINABLE; |
129 return; | 131 return; |
130 } | 132 } |
131 DCHECK(ARMED == watchdog_->state_); | 133 DCHECK(ARMED == watchdog_->state_); |
132 remaining_duration = watchdog_->duration_ - | 134 remaining_duration = watchdog_->duration_ - |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
168 } | 170 } |
169 | 171 |
170 void Watchdog::ThreadDelegate::SetThreadName() const { | 172 void Watchdog::ThreadDelegate::SetThreadName() const { |
171 std::string name = watchdog_->thread_watched_name_ + " Watchdog"; | 173 std::string name = watchdog_->thread_watched_name_ + " Watchdog"; |
172 PlatformThread::SetName(name); | 174 PlatformThread::SetName(name); |
173 DVLOG(1) << "Watchdog active: " << name; | 175 DVLOG(1) << "Watchdog active: " << name; |
174 } | 176 } |
175 | 177 |
176 // static | 178 // static |
177 void Watchdog::ResetStaticData() { | 179 void Watchdog::ResetStaticData() { |
178 StaticData* static_data = g_static_data.Pointer(); | 180 StaticData* static_data = GetStaticData(); |
179 AutoLock lock(static_data->lock); | 181 AutoLock lock(static_data->lock); |
180 static_data->last_debugged_alarm_time = TimeTicks(); | 182 static_data->last_debugged_alarm_time = TimeTicks(); |
181 static_data->last_debugged_alarm_delay = TimeDelta(); | 183 static_data->last_debugged_alarm_delay = TimeDelta(); |
182 } | 184 } |
183 | 185 |
184 } // namespace base | 186 } // namespace base |
OLD | NEW |