| 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 |