Index: Source/platform/LifecycleNotifier.h |
diff --git a/Source/platform/LifecycleNotifier.h b/Source/platform/LifecycleNotifier.h |
index 1f97d775f7f0f9b13941e2baf6528344808d1ab8..8fb6c51df6c953e51c28858c45b1d18a231766de 100644 |
--- a/Source/platform/LifecycleNotifier.h |
+++ b/Source/platform/LifecycleNotifier.h |
@@ -34,8 +34,10 @@ |
namespace blink { |
+// Using a virtual inheritance to resolve a diamond inheritance |
+// in ExecutionContext. |
template<typename T> |
-class LifecycleNotifier { |
+class LifecycleNotifier : public virtual WillBeGarbageCollectedMixin { |
public: |
typedef LifecycleObserver<T> Observer; |
typedef T Context; |
@@ -53,7 +55,11 @@ public: |
virtual void addObserver(Observer*); |
virtual void removeObserver(Observer*); |
- virtual void trace(Visitor*) { } |
+ virtual void trace(Visitor* visitor) |
+ { |
+ visitor->trace(m_context); |
+ visitor->trace(m_observers); |
+ } |
bool isIteratingOverObservers() const { return m_iterating != IteratingNone; } |
@@ -65,7 +71,7 @@ protected: |
{ |
} |
- Context* context() const { return m_context; } |
+ Context* context() const { return m_context.get(); } |
enum IterationType { |
IteratingNone, |
@@ -79,20 +85,20 @@ protected: |
IterationType m_iterating; |
private: |
- typedef HashSet<Observer*> ObserverSet; |
+ typedef WillBeHeapHashSet<RawPtrWillBeMember<Observer>> ObserverSet; |
ObserverSet m_observers; |
- Context* m_context; |
+ RawPtrWillBeWeakMember<Context> m_context; |
bool m_didCallContextDestroyed; |
}; |
template<typename T> |
inline LifecycleNotifier<T>::~LifecycleNotifier() |
{ |
+#if !ENABLE(OILPAN) |
// FIXME: Enable the following ASSERT. Also see a FIXME in Document::detach(). |
// ASSERT(!m_observers.size() || m_didCallContextDestroyed); |
-#if !ENABLE(OILPAN) |
TemporaryChange<IterationType> scope(this->m_iterating, IteratingOverAll); |
for (Observer* observer : m_observers) { |
ASSERT(observer->lifecycleContext() == m_context); |
@@ -109,6 +115,12 @@ inline void LifecycleNotifier<T>::notifyContextDestroyed() |
return; |
TemporaryChange<IterationType> scope(this->m_iterating, IteratingOverAll); |
+#if ENABLE(OILPAN) |
+ for (Observer* observer : m_observers) { |
+ ASSERT(observer->lifecycleContext() == m_context); |
+ observer->contextDestroyed(); |
+ } |
+#else |
Vector<Observer*> snapshotOfObservers; |
copyToVector(m_observers, snapshotOfObservers); |
for (Observer* observer : snapshotOfObservers) { |
@@ -122,6 +134,7 @@ inline void LifecycleNotifier<T>::notifyContextDestroyed() |
observer->contextDestroyed(); |
} |
} |
+#endif |
m_didCallContextDestroyed = true; |
} |
@@ -135,6 +148,9 @@ inline void LifecycleNotifier<T>::addObserver(typename LifecycleNotifier<T>::Obs |
template<typename T> |
inline void LifecycleNotifier<T>::removeObserver(typename LifecycleNotifier<T>::Observer* observer) |
{ |
+#if ENABLE(OILPAN) |
+ RELEASE_ASSERT(m_iterating != IteratingOverAll); |
+#endif |
m_observers.remove(observer); |
} |