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