watchdog.h 3.1 KB

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