OLD | NEW |
1 // Copyright (c) 2011 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" | 8 #include "base/lazy_instance.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/threading/platform_thread.h" | 10 #include "base/threading/platform_thread.h" |
11 | 11 |
(...skipping 17 matching lines...) Expand all Loading... |
29 | 29 |
30 // How long did we sit on a break in the debugger? | 30 // How long did we sit on a break in the debugger? |
31 TimeDelta g_last_debugged_alarm_delay; | 31 TimeDelta g_last_debugged_alarm_delay; |
32 | 32 |
33 } // namespace | 33 } // namespace |
34 | 34 |
35 // Start thread running in a Disarmed state. | 35 // Start thread running in a Disarmed state. |
36 Watchdog::Watchdog(const TimeDelta& duration, | 36 Watchdog::Watchdog(const TimeDelta& duration, |
37 const std::string& thread_watched_name, | 37 const std::string& thread_watched_name, |
38 bool enabled) | 38 bool enabled) |
39 : init_successful_(false), | 39 : enabled_(enabled), |
40 lock_(), | 40 lock_(), |
41 condition_variable_(&lock_), | 41 condition_variable_(&lock_), |
42 state_(DISARMED), | 42 state_(DISARMED), |
43 duration_(duration), | 43 duration_(duration), |
44 thread_watched_name_(thread_watched_name), | 44 thread_watched_name_(thread_watched_name), |
45 ALLOW_THIS_IN_INITIALIZER_LIST(delegate_(this)) { | 45 ALLOW_THIS_IN_INITIALIZER_LIST(delegate_(this)) { |
46 if (!enabled) | 46 if (!enabled_) |
47 return; // Don't start thread, or doing anything really. | 47 return; // Don't start thread, or doing anything really. |
48 init_successful_ = PlatformThread::Create(0, // Default stack size. | 48 enabled_ = PlatformThread::Create(0, // Default stack size. |
49 &delegate_, | 49 &delegate_, |
50 &handle_); | 50 &handle_); |
51 DCHECK(init_successful_); | 51 DCHECK(enabled_); |
52 } | 52 } |
53 | 53 |
54 // Notify watchdog thread, and wait for it to finish up. | 54 // Notify watchdog thread, and wait for it to finish up. |
55 Watchdog::~Watchdog() { | 55 Watchdog::~Watchdog() { |
56 if (!init_successful_) | 56 if (!enabled_) |
| 57 return; |
| 58 if (!IsJoinable()) |
| 59 Cleanup(); |
| 60 condition_variable_.Signal(); |
| 61 PlatformThread::Join(handle_); |
| 62 } |
| 63 |
| 64 void Watchdog::Cleanup() { |
| 65 if (!enabled_) |
57 return; | 66 return; |
58 { | 67 { |
59 AutoLock lock(lock_); | 68 AutoLock lock(lock_); |
60 state_ = SHUTDOWN; | 69 state_ = SHUTDOWN; |
61 } | 70 } |
62 condition_variable_.Signal(); | 71 condition_variable_.Signal(); |
63 PlatformThread::Join(handle_); | 72 } |
| 73 |
| 74 bool Watchdog::IsJoinable() { |
| 75 if (!enabled_) |
| 76 return true; |
| 77 AutoLock lock(lock_); |
| 78 return (state_ == JOINABLE); |
64 } | 79 } |
65 | 80 |
66 void Watchdog::Arm() { | 81 void Watchdog::Arm() { |
67 ArmAtStartTime(TimeTicks::Now()); | 82 ArmAtStartTime(TimeTicks::Now()); |
68 } | 83 } |
69 | 84 |
70 void Watchdog::ArmSomeTimeDeltaAgo(const TimeDelta& time_delta) { | 85 void Watchdog::ArmSomeTimeDeltaAgo(const TimeDelta& time_delta) { |
71 ArmAtStartTime(TimeTicks::Now() - time_delta); | 86 ArmAtStartTime(TimeTicks::Now() - time_delta); |
72 } | 87 } |
73 | 88 |
(...skipping 24 matching lines...) Expand all Loading... |
98 //------------------------------------------------------------------------------ | 113 //------------------------------------------------------------------------------ |
99 // Internal private methods that the watchdog thread uses. | 114 // Internal private methods that the watchdog thread uses. |
100 | 115 |
101 void Watchdog::ThreadDelegate::ThreadMain() { | 116 void Watchdog::ThreadDelegate::ThreadMain() { |
102 SetThreadName(); | 117 SetThreadName(); |
103 TimeDelta remaining_duration; | 118 TimeDelta remaining_duration; |
104 while (1) { | 119 while (1) { |
105 AutoLock lock(watchdog_->lock_); | 120 AutoLock lock(watchdog_->lock_); |
106 while (DISARMED == watchdog_->state_) | 121 while (DISARMED == watchdog_->state_) |
107 watchdog_->condition_variable_.Wait(); | 122 watchdog_->condition_variable_.Wait(); |
108 if (SHUTDOWN == watchdog_->state_) | 123 if (SHUTDOWN == watchdog_->state_) { |
| 124 watchdog_->state_ = JOINABLE; |
109 return; | 125 return; |
| 126 } |
110 DCHECK(ARMED == watchdog_->state_); | 127 DCHECK(ARMED == watchdog_->state_); |
111 remaining_duration = watchdog_->duration_ - | 128 remaining_duration = watchdog_->duration_ - |
112 (TimeTicks::Now() - watchdog_->start_time_); | 129 (TimeTicks::Now() - watchdog_->start_time_); |
113 if (remaining_duration.InMilliseconds() > 0) { | 130 if (remaining_duration.InMilliseconds() > 0) { |
114 // Spurios wake? Timer drifts? Go back to sleep for remaining time. | 131 // Spurios wake? Timer drifts? Go back to sleep for remaining time. |
115 watchdog_->condition_variable_.TimedWait(remaining_duration); | 132 watchdog_->condition_variable_.TimedWait(remaining_duration); |
116 continue; | 133 continue; |
117 } | 134 } |
118 // We overslept, so this seems like a real alarm. | 135 // We overslept, so this seems like a real alarm. |
119 // Watch out for a user that stopped the debugger on a different alarm! | 136 // Watch out for a user that stopped the debugger on a different alarm! |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 } | 170 } |
154 | 171 |
155 // static | 172 // static |
156 void Watchdog::ResetStaticData() { | 173 void Watchdog::ResetStaticData() { |
157 AutoLock lock(*g_static_lock.Pointer()); | 174 AutoLock lock(*g_static_lock.Pointer()); |
158 g_last_debugged_alarm_time = TimeTicks(); | 175 g_last_debugged_alarm_time = TimeTicks(); |
159 g_last_debugged_alarm_delay = TimeDelta(); | 176 g_last_debugged_alarm_delay = TimeDelta(); |
160 } | 177 } |
161 | 178 |
162 } // namespace base | 179 } // namespace base |
OLD | NEW |