summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorphajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-27 08:12:55 +0000
committerphajdan.jr@chromium.org <phajdan.jr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-27 08:12:55 +0000
commitbc732c29295ddd05a8bf2348b6848897acd27352 (patch)
treedd7110eb71976d7c92510cd19c07d2102bc4bce9
parentb9fe294776b6b5a1103cfa9a354895a95cae2738 (diff)
downloadchromium_src-bc732c29295ddd05a8bf2348b6848897acd27352.zip
chromium_src-bc732c29295ddd05a8bf2348b6848897acd27352.tar.gz
chromium_src-bc732c29295ddd05a8bf2348b6848897acd27352.tar.bz2
Do not monitor system power state during unit tests.
The observer requires that message loop stays up and same through its lifetime. This is not true during testing. TEST=none http://crbug.com/12187 Review URL: http://codereview.chromium.org/113824 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@16976 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--base/test_suite.h10
-rw-r--r--base/time.h7
-rw-r--r--base/time_win.cc105
-rw-r--r--chrome/browser/browser_main.cc5
4 files changed, 95 insertions, 32 deletions
diff --git a/base/test_suite.h b/base/test_suite.h
index 79fe5cf..584b945 100644
--- a/base/test_suite.h
+++ b/base/test_suite.h
@@ -18,6 +18,7 @@
#include "base/logging.h"
#include "base/multiprocess_test.h"
#include "base/scoped_nsautorelease_pool.h"
+#include "base/time.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/multiprocess_func_list.h"
@@ -108,6 +109,11 @@ class TestSuite {
logging::SetLogItems(true, true, true, true);
#if defined(OS_WIN)
+ // For unit tests we turn on the high resolution timer and disable
+ // base::Time's use of SystemMonitor. Tests create and destroy the message
+ // loop, which causes a crash with SystemMonitor (http://crbug.com/12187).
+ base::Time::EnableHiResClockForTests();
+
// In some cases, we do not want to see standard error dialogs.
if (!IsDebuggerPresent() &&
!CommandLine::ForCurrentProcess()->HasSwitch(L"show-error-dialogs")) {
@@ -116,9 +122,9 @@ class TestSuite {
// When the code in this file moved around, bug 6436 resurfaced.
// As a hack workaround, just #ifdef out this code for Purify builds.
logging::SetLogAssertHandler(UnitTestAssertHandler);
-#endif
+#endif // !defined(PURIFY)
}
-#endif
+#endif // defined(OS_WIN)
icu_util::Initialize();
}
diff --git a/base/time.h b/base/time.h
index 0625bfb..beeca27 100644
--- a/base/time.h
+++ b/base/time.h
@@ -228,6 +228,13 @@ class Time {
#if defined(OS_WIN)
static Time FromFileTime(FILETIME ft);
FILETIME ToFileTime() const;
+
+ // Monitor system power state and disable high resolution timer when we're
+ // on battery. See time_win.cc for more details.
+ static void StartSystemMonitorObserver();
+
+ // Enable high resolution timer unconditionally. Only for test code.
+ static void EnableHiResClockForTests();
#endif
// Converts an exploded structure representing either the local time or UTC
diff --git a/base/time_win.cc b/base/time_win.cc
index fa24868..d0c9702 100644
--- a/base/time_win.cc
+++ b/base/time_win.cc
@@ -88,6 +88,69 @@ void InitializeClock() {
initial_time = CurrentWallclockMicroseconds();
}
+class HighResolutionTimerManager : public base::SystemMonitor::PowerObserver {
+ public:
+ ~HighResolutionTimerManager() {
+ StopMonitoring();
+ UseHiResClock(false);
+ }
+
+ void Enable() {
+ StopMonitoring();
+ UseHiResClock(true);
+ }
+
+ void StartMonitoring() {
+ if (is_monitoring_)
+ return;
+ is_monitoring_ = true;
+ base::SystemMonitor* system = base::SystemMonitor::Get();
+ DCHECK(system);
+ system->AddObserver(this);
+ UseHiResClock(!system->BatteryPower());
+ }
+
+ void StopMonitoring() {
+ if (!is_monitoring_)
+ return;
+ is_monitoring_ = false;
+ base::SystemMonitor* monitor = base::SystemMonitor::Get();
+ if (monitor)
+ monitor->RemoveObserver(this);
+ }
+
+ // Interfaces for monitoring Power changes.
+ void OnPowerStateChange(base::SystemMonitor* system) {
+ UseHiResClock(!system->BatteryPower());
+ }
+
+ void OnSuspend(base::SystemMonitor* system) {}
+ void OnResume(base::SystemMonitor* system) {}
+
+ private:
+ HighResolutionTimerManager()
+ : is_monitoring_(false),
+ hi_res_clock_enabled_(false) {
+ }
+ friend struct DefaultSingletonTraits<HighResolutionTimerManager>;
+
+ // Enable or disable the faster multimedia timer.
+ void UseHiResClock(bool enabled) {
+ if (enabled == hi_res_clock_enabled_)
+ return;
+ if (enabled)
+ timeBeginPeriod(1);
+ else
+ timeEndPeriod(1);
+ hi_res_clock_enabled_ = enabled;
+ }
+
+ bool is_monitoring_;
+ bool hi_res_clock_enabled_;
+
+ DISALLOW_COPY_AND_ASSIGN(HighResolutionTimerManager);
+};
+
} // namespace
// Time -----------------------------------------------------------------------
@@ -149,6 +212,16 @@ FILETIME Time::ToFileTime() const {
}
// static
+void Time::StartSystemMonitorObserver() {
+ Singleton<HighResolutionTimerManager>()->StartMonitoring();
+}
+
+// static
+void Time::EnableHiResClockForTests() {
+ Singleton<HighResolutionTimerManager>()->Enable();
+}
+
+// static
Time Time::FromExploded(bool is_local, const Exploded& exploded) {
// Create the system struct representing our exploded time. It will either be
// in local time or UTC.
@@ -227,22 +300,14 @@ DWORD (*tick_function)(void) = &timeGetTimeWrapper;
// which will roll over the 32-bit value every ~49 days. We try to track
// rollover ourselves, which works if TimeTicks::Now() is called at least every
// 49 days.
-class NowSingleton : public base::SystemMonitor::PowerObserver {
+class NowSingleton {
public:
NowSingleton()
: rollover_(TimeDelta::FromMilliseconds(0)),
- last_seen_(0),
- hi_res_clock_enabled_(false) {
- base::SystemMonitor* system = base::SystemMonitor::Get();
- system->AddObserver(this);
- UseHiResClock(!system->BatteryPower());
+ last_seen_(0) {
}
~NowSingleton() {
- UseHiResClock(false);
- base::SystemMonitor* monitor = base::SystemMonitor::Get();
- if (monitor)
- monitor->RemoveObserver(this);
}
TimeDelta Now() {
@@ -256,30 +321,10 @@ class NowSingleton : public base::SystemMonitor::PowerObserver {
return TimeDelta::FromMilliseconds(now) + rollover_;
}
- // Interfaces for monitoring Power changes.
- void OnPowerStateChange(base::SystemMonitor* system) {
- UseHiResClock(!system->BatteryPower());
- }
-
- void OnSuspend(base::SystemMonitor* system) {}
- void OnResume(base::SystemMonitor* system) {}
-
private:
- // Enable or disable the faster multimedia timer.
- void UseHiResClock(bool enabled) {
- if (enabled == hi_res_clock_enabled_)
- return;
- if (enabled)
- timeBeginPeriod(1);
- else
- timeEndPeriod(1);
- hi_res_clock_enabled_ = enabled;
- }
-
Lock lock_; // To protected last_seen_ and rollover_.
TimeDelta rollover_; // Accumulation of time lost due to rollover.
DWORD last_seen_; // The last timeGetTime value we saw, to detect rollover.
- bool hi_res_clock_enabled_;
DISALLOW_COPY_AND_ASSIGN(NowSingleton);
};
diff --git a/chrome/browser/browser_main.cc b/chrome/browser/browser_main.cc
index d2bc9de..5b955eb 100644
--- a/chrome/browser/browser_main.cc
+++ b/chrome/browser/browser_main.cc
@@ -265,6 +265,11 @@ int BrowserMain(const MainFunctionParams& parameters) {
// Initialize the SystemMonitor
base::SystemMonitor::Start();
+#if defined(OS_WIN)
+ // We want to monitor system power state to adjust our high resolution
+ // timer settings. But it's necessary only on Windows.
+ base::Time::StartSystemMonitorObserver();
+#endif // defined(OS_WIN)
// Initialize statistical testing infrastructure.
FieldTrialList field_trial;