1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors 2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file. 4*6777b538SAndroid Build Coastguard Worker 5*6777b538SAndroid Build Coastguard Worker // The Watchdog class creates a second thread that can Alarm if a specific 6*6777b538SAndroid Build Coastguard Worker // duration of time passes without proper attention. The duration of time is 7*6777b538SAndroid Build Coastguard Worker // specified at construction time. The Watchdog may be used many times by 8*6777b538SAndroid Build Coastguard Worker // simply calling Arm() (to start timing) and Disarm() (to reset the timer). 9*6777b538SAndroid Build Coastguard Worker // The Watchdog is typically used under a debugger, where the stack traces on 10*6777b538SAndroid Build Coastguard Worker // other threads can be examined if/when the Watchdog alarms. 11*6777b538SAndroid Build Coastguard Worker 12*6777b538SAndroid Build Coastguard Worker // Some watchdogs will be enabled or disabled via command line switches. To 13*6777b538SAndroid Build Coastguard Worker // facilitate such code, an "enabled" argument for the constuctor can be used 14*6777b538SAndroid Build Coastguard Worker // to permanently disable the watchdog. Disabled watchdogs don't even spawn 15*6777b538SAndroid Build Coastguard Worker // a second thread, and their methods call (Arm() and Disarm()) return very 16*6777b538SAndroid Build Coastguard Worker // quickly. 17*6777b538SAndroid Build Coastguard Worker 18*6777b538SAndroid Build Coastguard Worker #ifndef BASE_THREADING_WATCHDOG_H_ 19*6777b538SAndroid Build Coastguard Worker #define BASE_THREADING_WATCHDOG_H_ 20*6777b538SAndroid Build Coastguard Worker 21*6777b538SAndroid Build Coastguard Worker #include <string> 22*6777b538SAndroid Build Coastguard Worker 23*6777b538SAndroid Build Coastguard Worker #include "base/base_export.h" 24*6777b538SAndroid Build Coastguard Worker #include "base/compiler_specific.h" 25*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr.h" 26*6777b538SAndroid Build Coastguard Worker #include "base/synchronization/condition_variable.h" 27*6777b538SAndroid Build Coastguard Worker #include "base/synchronization/lock.h" 28*6777b538SAndroid Build Coastguard Worker #include "base/threading/platform_thread.h" 29*6777b538SAndroid Build Coastguard Worker #include "base/time/time.h" 30*6777b538SAndroid Build Coastguard Worker 31*6777b538SAndroid Build Coastguard Worker namespace base { 32*6777b538SAndroid Build Coastguard Worker 33*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT Watchdog { 34*6777b538SAndroid Build Coastguard Worker public: 35*6777b538SAndroid Build Coastguard Worker class Delegate { 36*6777b538SAndroid Build Coastguard Worker public: 37*6777b538SAndroid Build Coastguard Worker virtual ~Delegate() = default; 38*6777b538SAndroid Build Coastguard Worker 39*6777b538SAndroid Build Coastguard Worker // Called on the watchdog thread. 40*6777b538SAndroid Build Coastguard Worker virtual void Alarm() = 0; 41*6777b538SAndroid Build Coastguard Worker }; 42*6777b538SAndroid Build Coastguard Worker 43*6777b538SAndroid Build Coastguard Worker // Constructor specifies how long the Watchdog will wait before alarming. If 44*6777b538SAndroid Build Coastguard Worker // `delegate` is non-null, `Alarm` on the delegate will be called instead of 45*6777b538SAndroid Build Coastguard Worker // the default behavior. 46*6777b538SAndroid Build Coastguard Worker Watchdog(const TimeDelta& duration, 47*6777b538SAndroid Build Coastguard Worker const std::string& thread_watched_name, 48*6777b538SAndroid Build Coastguard Worker bool enabled, 49*6777b538SAndroid Build Coastguard Worker Delegate* delegate = nullptr); 50*6777b538SAndroid Build Coastguard Worker 51*6777b538SAndroid Build Coastguard Worker Watchdog(const Watchdog&) = delete; 52*6777b538SAndroid Build Coastguard Worker Watchdog& operator=(const Watchdog&) = delete; 53*6777b538SAndroid Build Coastguard Worker 54*6777b538SAndroid Build Coastguard Worker ~Watchdog(); 55*6777b538SAndroid Build Coastguard Worker 56*6777b538SAndroid Build Coastguard Worker // Notify watchdog thread to finish up. Sets the state_ to SHUTDOWN. 57*6777b538SAndroid Build Coastguard Worker void Cleanup(); 58*6777b538SAndroid Build Coastguard Worker 59*6777b538SAndroid Build Coastguard Worker // Returns true if we state_ is JOINABLE (which indicates that Watchdog has 60*6777b538SAndroid Build Coastguard Worker // exited). 61*6777b538SAndroid Build Coastguard Worker bool IsJoinable(); 62*6777b538SAndroid Build Coastguard Worker 63*6777b538SAndroid Build Coastguard Worker // Start timing, and alarm when time expires (unless we're disarm()ed.) 64*6777b538SAndroid Build Coastguard Worker void Arm(); // Arm starting now. 65*6777b538SAndroid Build Coastguard Worker void ArmSomeTimeDeltaAgo(const TimeDelta& time_delta); 66*6777b538SAndroid Build Coastguard Worker void ArmAtStartTime(const TimeTicks start_time); 67*6777b538SAndroid Build Coastguard Worker 68*6777b538SAndroid Build Coastguard Worker // Reset time, and do not set off the alarm. 69*6777b538SAndroid Build Coastguard Worker void Disarm(); 70*6777b538SAndroid Build Coastguard Worker 71*6777b538SAndroid Build Coastguard Worker // Alarm is called if the time expires after an Arm() without someone calling 72*6777b538SAndroid Build Coastguard Worker // Disarm(). 73*6777b538SAndroid Build Coastguard Worker void Alarm(); 74*6777b538SAndroid Build Coastguard Worker 75*6777b538SAndroid Build Coastguard Worker // Reset static data to initial state. Useful for tests, to ensure 76*6777b538SAndroid Build Coastguard Worker // they are independent. 77*6777b538SAndroid Build Coastguard Worker static void ResetStaticData(); 78*6777b538SAndroid Build Coastguard Worker 79*6777b538SAndroid Build Coastguard Worker // The default behavior of Alarm() if a delegate is not provided. 80*6777b538SAndroid Build Coastguard Worker void DefaultAlarm(); 81*6777b538SAndroid Build Coastguard Worker 82*6777b538SAndroid Build Coastguard Worker private: 83*6777b538SAndroid Build Coastguard Worker class ThreadDelegate : public PlatformThread::Delegate { 84*6777b538SAndroid Build Coastguard Worker public: ThreadDelegate(Watchdog * watchdog)85*6777b538SAndroid Build Coastguard Worker explicit ThreadDelegate(Watchdog* watchdog) : watchdog_(watchdog) { 86*6777b538SAndroid Build Coastguard Worker } 87*6777b538SAndroid Build Coastguard Worker void ThreadMain() override; 88*6777b538SAndroid Build Coastguard Worker 89*6777b538SAndroid Build Coastguard Worker private: 90*6777b538SAndroid Build Coastguard Worker void SetThreadName() const; 91*6777b538SAndroid Build Coastguard Worker 92*6777b538SAndroid Build Coastguard Worker raw_ptr<Watchdog> watchdog_; 93*6777b538SAndroid Build Coastguard Worker }; 94*6777b538SAndroid Build Coastguard Worker 95*6777b538SAndroid Build Coastguard Worker enum State { ARMED, DISARMED, SHUTDOWN, JOINABLE }; 96*6777b538SAndroid Build Coastguard Worker 97*6777b538SAndroid Build Coastguard Worker bool enabled_; 98*6777b538SAndroid Build Coastguard Worker 99*6777b538SAndroid Build Coastguard Worker Lock lock_; 100*6777b538SAndroid Build Coastguard Worker ConditionVariable condition_variable_; 101*6777b538SAndroid Build Coastguard Worker State state_ GUARDED_BY(lock_); 102*6777b538SAndroid Build Coastguard Worker const TimeDelta duration_; // How long after start_time_ do we alarm? 103*6777b538SAndroid Build Coastguard Worker const std::string thread_watched_name_; 104*6777b538SAndroid Build Coastguard Worker PlatformThreadHandle handle_; 105*6777b538SAndroid Build Coastguard Worker ThreadDelegate thread_delegate_; // Must outlive the thread. 106*6777b538SAndroid Build Coastguard Worker 107*6777b538SAndroid Build Coastguard Worker raw_ptr<Delegate> delegate_; 108*6777b538SAndroid Build Coastguard Worker TimeTicks start_time_; // Start of epoch, and alarm after duration_. 109*6777b538SAndroid Build Coastguard Worker }; 110*6777b538SAndroid Build Coastguard Worker 111*6777b538SAndroid Build Coastguard Worker } // namespace base 112*6777b538SAndroid Build Coastguard Worker 113*6777b538SAndroid Build Coastguard Worker #endif // BASE_THREADING_WATCHDOG_H_ 114