From 012b3711f9b51af158598adc2f65e8b667f975a3 Mon Sep 17 00:00:00 2001 From: bajones Date: Wed, 3 Sep 2014 17:11:05 -0700 Subject: Check to ensure PowerObservers are added and removed on the same thread This behavior is required by ObserverListThreadSafe and may leads to crashes if not followed BUG=404767 Review URL: https://codereview.chromium.org/502003003 Cr-Commit-Position: refs/heads/master@{#293230} --- base/BUILD.gn | 1 + base/base.gypi | 1 + base/power_monitor/power_monitor.cc | 7 +++++++ base/power_monitor/power_observer.cc | 15 +++++++++++++++ base/power_monitor/power_observer.h | 15 +++++++++++++-- 5 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 base/power_monitor/power_observer.cc (limited to 'base') diff --git a/base/BUILD.gn b/base/BUILD.gn index f4c8ab7..65e2d64 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn @@ -448,6 +448,7 @@ component("base") { "power_monitor/power_monitor_device_source_win.cc", "power_monitor/power_monitor_source.cc", "power_monitor/power_monitor_source.h", + "power_monitor/power_observer.cc", "power_monitor/power_observer.h", "process/internal_linux.cc", "process/internal_linux.h", diff --git a/base/base.gypi b/base/base.gypi index cfa9d61..c64061b 100644 --- a/base/base.gypi +++ b/base/base.gypi @@ -439,6 +439,7 @@ 'power_monitor/power_monitor_device_source_win.cc', 'power_monitor/power_monitor_source.cc', 'power_monitor/power_monitor_source.h', + 'power_monitor/power_observer.cc', 'power_monitor/power_observer.h', 'process/internal_linux.cc', 'process/internal_linux.h', diff --git a/base/power_monitor/power_monitor.cc b/base/power_monitor/power_monitor.cc index 14dc4b5..547318e 100644 --- a/base/power_monitor/power_monitor.cc +++ b/base/power_monitor/power_monitor.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "base/power_monitor/power_monitor.h" +#include "base/logging.h" #include "base/power_monitor/power_monitor_source.h" namespace base { @@ -27,11 +28,17 @@ PowerMonitor* PowerMonitor::Get() { } void PowerMonitor::AddObserver(PowerObserver* obs) { + DCHECK(!obs->power_monitor_thread_checker_); + obs->power_monitor_thread_checker_.reset(new base::ThreadChecker()); observers_->AddObserver(obs); } void PowerMonitor::RemoveObserver(PowerObserver* obs) { + // PowerObservers must be removed on the same thread on which they were added. + DCHECK(obs->power_monitor_thread_checker_); + DCHECK(obs->power_monitor_thread_checker_->CalledOnValidThread()); observers_->RemoveObserver(obs); + obs->power_monitor_thread_checker_.reset(); } PowerMonitorSource* PowerMonitor::Source() { diff --git a/base/power_monitor/power_observer.cc b/base/power_monitor/power_observer.cc new file mode 100644 index 0000000..2642809 --- /dev/null +++ b/base/power_monitor/power_observer.cc @@ -0,0 +1,15 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/power_monitor/power_observer.h" + +namespace base { + +PowerObserver::PowerObserver() { +} + +PowerObserver::~PowerObserver() { +} + +} // namespace base diff --git a/base/power_monitor/power_observer.h b/base/power_monitor/power_observer.h index 6be70bb..e7d40a3 100644 --- a/base/power_monitor/power_observer.h +++ b/base/power_monitor/power_observer.h @@ -7,14 +7,20 @@ #include "base/base_export.h" #include "base/compiler_specific.h" +#include "base/memory/scoped_ptr.h" +#include "base/threading/thread_checker.h" namespace base { class BASE_EXPORT PowerObserver { + friend class PowerMonitor; + public: + PowerObserver(); + // Notification of a change in power status of the computer, such // as from switching between battery and A/C power. - virtual void OnPowerStateChange(bool on_battery_power) {}; + virtual void OnPowerStateChange(bool on_battery_power) {} // Notification that the system is suspending. virtual void OnSuspend() {} @@ -23,7 +29,12 @@ class BASE_EXPORT PowerObserver { virtual void OnResume() {} protected: - virtual ~PowerObserver() {} + virtual ~PowerObserver(); + + private: + // Allows PowerMonitor to ensure this observer is added and removed + // from the same thread, which is required by the ObserverListThreadSafe. + scoped_ptr power_monitor_thread_checker_; }; } // namespace base -- cgit v1.1