From 95ab1553ce02175cf23278d80b8440b27740159c Mon Sep 17 00:00:00 2001 From: "deanm@chromium.org" Date: Tue, 25 Nov 2008 22:46:59 +0000 Subject: Port base/watchdog to Linux. BUG=4632 Review URL: http://codereview.chromium.org/11326 Patch from Pawel Hajdan Jr. git-svn-id: svn://svn.chromium.org/chrome/trunk/src@6004 0039d316-1c4b-4281-b951-d872f2087c98 --- base/watchdog.cc | 77 ++++++++++++++++++++++---------------------------------- 1 file changed, 30 insertions(+), 47 deletions(-) (limited to 'base/watchdog.cc') diff --git a/base/watchdog.cc b/base/watchdog.cc index b1db70b..0049fec 100644 --- a/base/watchdog.cc +++ b/base/watchdog.cc @@ -4,8 +4,8 @@ #include "base/watchdog.h" +#include "base/compiler_specific.h" #include "base/platform_thread.h" -#include "base/string_util.h" using base::TimeDelta; using base::TimeTicks; @@ -15,42 +15,32 @@ using base::TimeTicks; // Start thread running in a Disarmed state. Watchdog::Watchdog(const TimeDelta& duration, - const std::wstring& thread_watched_name, + const std::string& thread_watched_name, bool enabled) - : lock_(), + : init_successful_(false), + lock_(), condition_variable_(&lock_), state_(DISARMED), - duration_(duration), thread_watched_name_(thread_watched_name), - handle_(NULL), - thread_id_(0) { + ALLOW_THIS_IN_INITIALIZER_LIST(delegate_(this, duration)) { if (!enabled) return; // Don't start thread, or doing anything really. - handle_ = CreateThread(NULL, // security - 0, // Default stack size. - Watchdog::ThreadStart, - reinterpret_cast(this), - CREATE_SUSPENDED, - &thread_id_); - DCHECK(NULL != handle_); - if (NULL == handle_) - return ; - ResumeThread(handle_); // WINAPI call. + init_successful_ = PlatformThread::Create(0, // Default stack size. + &delegate_, + &handle_); + DCHECK(init_successful_); } // Notify watchdog thread, and wait for it to finish up. Watchdog::~Watchdog() { - if (NULL == handle_) + if (!init_successful_) return; { AutoLock lock(lock_); state_ = SHUTDOWN; } condition_variable_.Signal(); - DWORD results = WaitForSingleObject(handle_, INFINITE); - DCHECK(WAIT_OBJECT_0 == results); - CloseHandle(handle_); - handle_ = NULL; + PlatformThread::Join(handle_); } void Watchdog::Arm() { @@ -75,8 +65,6 @@ void Watchdog::ArmAtStartTime(const TimeTicks start_time) { // Disable watchdog so that it won't do anything when time expires. void Watchdog::Disarm() { - if (NULL == handle_) - return; AutoLock lock(lock_); state_ = DISARMED; // We don't need to signal, as the watchdog will eventually wake up, and it @@ -86,43 +74,39 @@ void Watchdog::Disarm() { //------------------------------------------------------------------------------ // Internal private methods that the watchdog thread uses. -// static -DWORD __stdcall Watchdog::ThreadStart(void* pThis) { - Watchdog* watchdog = reinterpret_cast(pThis); - return watchdog->Run(); -} - -unsigned Watchdog::Run() { +void Watchdog::ThreadDelegate::ThreadMain() { SetThreadName(); TimeDelta remaining_duration; while (1) { - AutoLock lock(lock_); - while (DISARMED == state_) - condition_variable_.Wait(); - if (SHUTDOWN == state_) - return 0; - DCHECK(ARMED == state_); - remaining_duration = duration_ - (TimeTicks::Now() - start_time_); + AutoLock lock(watchdog_->lock_); + while (DISARMED == watchdog_->state_) + watchdog_->condition_variable_.Wait(); + if (SHUTDOWN == watchdog_->state_) + return; + DCHECK(ARMED == watchdog_->state_); + remaining_duration = duration_ - + (TimeTicks::Now() - watchdog_->start_time_); if (remaining_duration.InMilliseconds() > 0) { // Spurios wake? Timer drifts? Go back to sleep for remaining time. - condition_variable_.TimedWait(remaining_duration); + watchdog_->condition_variable_.TimedWait(remaining_duration); } else { // We overslept, so this seems like a real alarm. // Watch out for a user that stopped the debugger on a different alarm! { AutoLock static_lock(static_lock_); - if (last_debugged_alarm_time_ > start_time_) { + if (last_debugged_alarm_time_ > watchdog_->start_time_) { // False alarm: we started our clock before the debugger break (last // alarm time). - start_time_ += last_debugged_alarm_delay_; - if (last_debugged_alarm_time_ > start_time_) - state_ = DISARMED; // Too many alarms must have taken place. + watchdog_->start_time_ += last_debugged_alarm_delay_; + if (last_debugged_alarm_time_ > watchdog_->start_time_) + // Too many alarms must have taken place. + watchdog_->state_ = DISARMED; continue; } } - state_ = DISARMED; // Only alarm at most once. + watchdog_->state_ = DISARMED; // Only alarm at most once. TimeTicks last_alarm_time = TimeTicks::Now(); - Alarm(); // Set a break point here to debug on alarms. + watchdog_->Alarm(); // Set a break point here to debug on alarms. TimeDelta last_alarm_delay = TimeTicks::Now() - last_alarm_time; if (last_alarm_delay > TimeDelta::FromMilliseconds(2)) { // Ignore race of two alarms/breaks going off at roughly the same time. @@ -135,9 +119,8 @@ unsigned Watchdog::Run() { } } -void Watchdog::SetThreadName() const { - std::string name = StringPrintf("%s Watchdog", - WideToASCII(thread_watched_name_).c_str()); +void Watchdog::ThreadDelegate::SetThreadName() const { + std::string name = watchdog_->thread_watched_name_ + " Watchdog"; PlatformThread::SetName(name.c_str()); DLOG(INFO) << "Watchdog active: " << name; } -- cgit v1.1