Index: base/memory/memory_pressure_listener.cc |
diff --git a/base/memory/memory_pressure_listener.cc b/base/memory/memory_pressure_listener.cc |
index de63958b929edf86bd61f54be7d5e387129157f3..11859ada613f77cd9418e87351d17c2f948589b2 100644 |
--- a/base/memory/memory_pressure_listener.cc |
+++ b/base/memory/memory_pressure_listener.cc |
@@ -12,28 +12,48 @@ namespace base { |
namespace { |
-// ObserverListThreadSafe is RefCountedThreadSafe, this traits is needed |
-// to ensure the LazyInstance will hold a reference to it. |
-struct LeakyLazyObserverListTraits : |
- base::internal::LeakyLazyInstanceTraits< |
- ObserverListThreadSafe<MemoryPressureListener> > { |
- static ObserverListThreadSafe<MemoryPressureListener>* |
- New(void* instance) { |
- ObserverListThreadSafe<MemoryPressureListener>* ret = |
- base::internal::LeakyLazyInstanceTraits< |
- ObserverListThreadSafe<MemoryPressureListener>>::New(instance); |
- // Leaky. |
- ret->AddRef(); |
- return ret; |
+class MemoryPressureObserver { |
+ public: |
+ MemoryPressureObserver() |
+ : async_observers_(new ObserverListThreadSafe<MemoryPressureListener>), |
+ sync_observers_(new ObserverList<MemoryPressureListener>) { |
} |
+ |
+ void AddObserver(MemoryPressureListener* listener, bool sync) { |
+ async_observers_->AddObserver(listener); |
+ if (sync) { |
+ AutoLock lock(sync_observers_lock_); |
+ sync_observers_->AddObserver(listener); |
+ } |
+ } |
+ |
+ void RemoveObserver(MemoryPressureListener* listener) { |
+ async_observers_->RemoveObserver(listener); |
+ AutoLock lock(sync_observers_lock_); |
+ sync_observers_->RemoveObserver(listener); |
+ } |
+ |
+ void Notify(MemoryPressureListener::MemoryPressureLevel |
+ memory_pressure_level) { |
+ async_observers_->Notify(FROM_HERE, |
+ &MemoryPressureListener::Notify, memory_pressure_level); |
+ AutoLock lock(sync_observers_lock_); |
+ FOR_EACH_OBSERVER(MemoryPressureListener, *sync_observers_, |
+ MemoryPressureListener::SyncNotify(memory_pressure_level)); |
+ } |
+ |
+ private: |
+ scoped_refptr<ObserverListThreadSafe<MemoryPressureListener>> |
+ async_observers_; |
+ ObserverList<MemoryPressureListener>* sync_observers_; |
+ Lock sync_observers_lock_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(MemoryPressureObserver); |
}; |
-LazyInstance< |
- ObserverListThreadSafe<MemoryPressureListener>, |
- LeakyLazyObserverListTraits> g_observers = LAZY_INSTANCE_INITIALIZER; |
+LazyInstance<MemoryPressureObserver>::Leaky g_observer = |
+ LAZY_INSTANCE_INITIALIZER; |
-// All memory pressure notifications within this process will be suppressed if |
-// this variable is set to 1. |
subtle::Atomic32 g_notifications_suppressed = 0; |
} // namespace |
@@ -41,17 +61,33 @@ subtle::Atomic32 g_notifications_suppressed = 0; |
MemoryPressureListener::MemoryPressureListener( |
const MemoryPressureListener::MemoryPressureCallback& callback) |
: callback_(callback) { |
- g_observers.Get().AddObserver(this); |
+ g_observer.Get().AddObserver(this, false); |
+} |
+ |
+MemoryPressureListener::MemoryPressureListener( |
+ const MemoryPressureListener::MemoryPressureCallback& callback, |
+ const MemoryPressureListener::SyncMemoryPressureCallback& |
+ sync_memory_pressure_callback) |
+ : callback_(callback), |
+ sync_memory_pressure_callback_(sync_memory_pressure_callback) { |
+ g_observer.Get().AddObserver(this, true); |
} |
MemoryPressureListener::~MemoryPressureListener() { |
- g_observers.Get().RemoveObserver(this); |
+ g_observer.Get().RemoveObserver(this); |
} |
void MemoryPressureListener::Notify(MemoryPressureLevel memory_pressure_level) { |
callback_.Run(memory_pressure_level); |
} |
+void MemoryPressureListener::SyncNotify( |
+ MemoryPressureLevel memory_pressure_level) { |
+ if (!sync_memory_pressure_callback_.is_null()) { |
+ sync_memory_pressure_callback_.Run(memory_pressure_level); |
+ } |
+} |
+ |
// static |
void MemoryPressureListener::NotifyMemoryPressure( |
MemoryPressureLevel memory_pressure_level) { |
@@ -86,8 +122,8 @@ void MemoryPressureListener::SimulatePressureNotification( |
void MemoryPressureListener::DoNotifyMemoryPressure( |
MemoryPressureLevel memory_pressure_level) { |
DCHECK_NE(memory_pressure_level, MEMORY_PRESSURE_LEVEL_NONE); |
- g_observers.Get().Notify(FROM_HERE, &MemoryPressureListener::Notify, |
- memory_pressure_level); |
+ |
+ g_observer.Get().Notify(memory_pressure_level); |
} |
} // namespace base |