license.bot | f003cfe | 2008-08-24 09:55:55 +0900 | [diff] [blame^] | 1 | // Copyright (c) 2006-2008 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. |
initial.commit | 3f4a732 | 2008-07-27 06:49:38 +0900 | [diff] [blame] | 4 | |
| 5 | // The Watchdog class creates a second thread that can Alarm if a specific |
| 6 | // duration of time passes without proper attention. The duration of time is |
| 7 | // specified at construction time. The Watchdog may be used many times by |
| 8 | // simply calling Arm() (to start timing) and Disarm() (to reset the timer). |
| 9 | // The Watchdog is typically used under a debugger, where the stack traces on |
| 10 | // other threads can be examined if/when the Watchdog alarms. |
| 11 | |
| 12 | // Some watchdogs will be enabled or disabled via command line switches. To |
| 13 | // facilitate such code, an "enabled" argument for the constuctor can be used |
| 14 | // to permanently disable the watchdog. Disabled watchdogs don't even spawn |
| 15 | // a second thread, and their methods call (Arm() and Disarm()) return very |
| 16 | // quickly. |
| 17 | |
| 18 | #ifndef BASE_WATCHDOG_H__ |
| 19 | #define BASE_WATCHDOG_H__ |
| 20 | |
| 21 | #include <string> |
| 22 | |
| 23 | #include "base/condition_variable.h" |
| 24 | #include "base/lock.h" |
| 25 | #include "base/time.h" |
| 26 | |
| 27 | class Watchdog { |
| 28 | public: |
| 29 | // TODO(JAR)change default arg to required arg after all users have migrated. |
| 30 | // Constructor specifies how long the Watchdog will wait before alarming. |
| 31 | Watchdog(const TimeDelta& duration, |
| 32 | const std::wstring& thread_watched_name, |
| 33 | bool enabled = true); |
| 34 | virtual ~Watchdog(); |
| 35 | |
| 36 | // Start timing, and alarm when time expires (unless we're disarm()ed.) |
| 37 | void Arm(); // Arm starting now. |
| 38 | void ArmSomeTimeDeltaAgo(const TimeDelta& time_delta); |
| 39 | void ArmAtStartTime(const TimeTicks start_time); |
| 40 | |
| 41 | // Reset time, and do not set off the alarm. |
| 42 | void Disarm(); |
| 43 | |
| 44 | // Alarm is called if the time expires after an Arm() without someone calling |
| 45 | // Disarm(). This method can be overridden to create testable classes. |
| 46 | virtual void Alarm() { |
| 47 | DLOG(INFO) << "Watchdog alarmed for " << thread_watched_name_; |
| 48 | } |
| 49 | |
| 50 | private: |
| 51 | enum State {ARMED, DISARMED, SHUTDOWN }; |
| 52 | |
| 53 | // Windows thread start callback |
| 54 | static DWORD WINAPI ThreadStart(void* pThis); |
| 55 | |
| 56 | // Loop and test function for our watchdog thread. |
| 57 | unsigned Run(); |
| 58 | void Watchdog::SetThreadName() const; |
| 59 | |
| 60 | Lock lock_; // Mutex for state_. |
| 61 | ConditionVariable condition_variable_; |
| 62 | State state_; |
| 63 | const TimeDelta duration_; // How long after start_time_ do we alarm? |
| 64 | const std::wstring thread_watched_name_; |
| 65 | HANDLE handle_; // Handle for watchdog thread. |
| 66 | DWORD thread_id_; // Also for watchdog thread. |
| 67 | |
| 68 | TimeTicks start_time_; // Start of epoch, and alarm after duration_. |
| 69 | |
| 70 | // When the debugger breaks (when we alarm), all the other alarms that are |
| 71 | // armed will expire (also alarm). To diminish this effect, we track any |
| 72 | // delay due to debugger breaks, and we *try* to adjust the effective start |
| 73 | // time of other alarms to step past the debugging break. |
| 74 | // Without this safety net, any alarm will typically trigger a host of follow |
| 75 | // on alarms from callers that specify old times. |
| 76 | static Lock static_lock_; // Lock for access of static data... |
| 77 | // When did we last alarm and get stuck (for a while) in a debugger? |
| 78 | static TimeTicks last_debugged_alarm_time_; |
| 79 | // How long did we sit on a break in the debugger? |
| 80 | static TimeDelta last_debugged_alarm_delay_; |
| 81 | |
| 82 | |
| 83 | DISALLOW_EVIL_CONSTRUCTORS(Watchdog); |
| 84 | }; |
| 85 | |
| 86 | #endif // BASE_WATCHDOG_H__ |
license.bot | f003cfe | 2008-08-24 09:55:55 +0900 | [diff] [blame^] | 87 | |