Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(733)

Unified Diff: Source/platform/LifecycleContextTest.cpp

Issue 973773002: Test observer removal&destruct during destroy notification. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: add fixme for future ref. Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/platform/LifecycleContextTest.cpp
diff --git a/Source/platform/LifecycleContextTest.cpp b/Source/platform/LifecycleContextTest.cpp
index eae437e48afbd5e7510c266afbf87dc6f9bd9feb..7998adfe22cd8bffef9967c90c532ebd363cc255 100644
--- a/Source/platform/LifecycleContextTest.cpp
+++ b/Source/platform/LifecycleContextTest.cpp
@@ -38,9 +38,9 @@ class TestingObserver;
class DummyContext final : public NoBaseWillBeGarbageCollectedFinalized<DummyContext>, public LifecycleNotifier<DummyContext, TestingObserver> {
public:
- DummyContext()
- : LifecycleNotifier<DummyContext, TestingObserver>(this)
+ static PassOwnPtrWillBeRawPtr<DummyContext> create()
{
+ return adoptPtrWillBeNoop(new DummyContext());
}
void addObserver(TestingObserver* observer)
@@ -57,58 +57,109 @@ public:
{
LifecycleNotifier<DummyContext, TestingObserver>::trace(visitor);
}
+
+private:
+ DummyContext()
+ : LifecycleNotifier<DummyContext, TestingObserver>(this)
+ {
+ }
};
class TestingObserver final : public NoBaseWillBeGarbageCollectedFinalized<TestingObserver>, public LifecycleObserver<DummyContext, TestingObserver, DummyContext> {
WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(TestingObserver);
public:
- explicit TestingObserver(DummyContext* context)
- : LifecycleObserver<DummyContext, TestingObserver, DummyContext>(context)
- , m_contextDestroyedCalled(false)
+ static PassOwnPtrWillBeRawPtr<TestingObserver> create(DummyContext* context)
{
- setContext(context);
+ return adoptPtrWillBeNoop(new TestingObserver(context));
}
virtual void contextDestroyed() override
{
LifecycleObserver<DummyContext, TestingObserver, DummyContext>::contextDestroyed();
+ if (m_observerToRemoveOnDestruct) {
+ lifecycleContext()->removeObserver(m_observerToRemoveOnDestruct.get());
+ m_observerToRemoveOnDestruct.clear();
+ }
m_contextDestroyedCalled = true;
}
DEFINE_INLINE_TRACE()
{
+ visitor->trace(m_observerToRemoveOnDestruct);
LifecycleObserver<DummyContext, TestingObserver, DummyContext>::trace(visitor);
}
- bool m_contextDestroyedCalled;
-
void unobserve() { setContext(nullptr); }
+
+ void setObserverToRemoveAndDestroy(PassOwnPtrWillBeRawPtr<TestingObserver> observerToRemoveOnDestruct)
+ {
+ ASSERT(!m_observerToRemoveOnDestruct);
+ m_observerToRemoveOnDestruct = observerToRemoveOnDestruct;
+ }
+
+ TestingObserver* innerObserver() const { return m_observerToRemoveOnDestruct.get(); }
+ bool contextDestroyedCalled() const { return m_contextDestroyedCalled; }
+
+private:
+ explicit TestingObserver(DummyContext* context)
+ : LifecycleObserver<DummyContext, TestingObserver, DummyContext>(context)
+ , m_contextDestroyedCalled(false)
+ {
+ setContext(context);
+ }
+
+ OwnPtrWillBeMember<TestingObserver> m_observerToRemoveOnDestruct;
+ bool m_contextDestroyedCalled;
};
TEST(LifecycleContextTest, shouldObserveContextDestroyed)
{
- OwnPtrWillBeRawPtr<DummyContext> context = adoptPtrWillBeNoop(new DummyContext());
- OwnPtrWillBePersistent<TestingObserver> observer = adoptPtrWillBeNoop(new TestingObserver(context.get()));
+ OwnPtrWillBeRawPtr<DummyContext> context = DummyContext::create();
+ OwnPtrWillBePersistent<TestingObserver> observer = TestingObserver::create(context.get());
EXPECT_EQ(observer->lifecycleContext(), context.get());
- EXPECT_FALSE(observer->m_contextDestroyedCalled);
+ EXPECT_FALSE(observer->contextDestroyedCalled());
context->notifyContextDestroyed();
context = nullptr;
Heap::collectAllGarbage();
EXPECT_EQ(observer->lifecycleContext(), static_cast<DummyContext*>(0));
- EXPECT_TRUE(observer->m_contextDestroyedCalled);
+ EXPECT_TRUE(observer->contextDestroyedCalled());
}
TEST(LifecycleContextTest, shouldNotObserveContextDestroyedIfUnobserve)
{
- OwnPtrWillBeRawPtr<DummyContext> context = adoptPtrWillBeNoop(new DummyContext());
- OwnPtrWillBePersistent<TestingObserver> observer = adoptPtrWillBeNoop(new TestingObserver(context.get()));
+ OwnPtrWillBeRawPtr<DummyContext> context = DummyContext::create();
+ OwnPtrWillBePersistent<TestingObserver> observer = TestingObserver::create(context.get());
observer->unobserve();
context->notifyContextDestroyed();
context = nullptr;
Heap::collectAllGarbage();
EXPECT_EQ(observer->lifecycleContext(), static_cast<DummyContext*>(0));
- EXPECT_FALSE(observer->m_contextDestroyedCalled);
+ EXPECT_FALSE(observer->contextDestroyedCalled());
}
+TEST(LifecycleContextTest, observerRemovedDuringNotifyDestroyed)
+{
+ // FIXME: Oilpan: this test can be removed when the LifecycleNotifier<T>::m_observers
+ // hash set is on the heap and membership is handled implicitly by the garbage collector.
+ OwnPtrWillBeRawPtr<DummyContext> context = DummyContext::create();
+ OwnPtrWillBePersistent<TestingObserver> observer = TestingObserver::create(context.get());
+ OwnPtrWillBeRawPtr<TestingObserver> innerObserver = TestingObserver::create(context.get());
+ // Attach the observer to the other. When 'observer' is notified
+ // of destruction, it will remove & destroy 'innerObserver'.
+ observer->setObserverToRemoveAndDestroy(innerObserver.release());
+
+ EXPECT_EQ(observer->lifecycleContext(), context.get());
+ EXPECT_EQ(observer->innerObserver()->lifecycleContext(), context.get());
+ EXPECT_FALSE(observer->contextDestroyedCalled());
+ EXPECT_FALSE(observer->innerObserver()->contextDestroyedCalled());
+
+ context->notifyContextDestroyed();
+ EXPECT_EQ(observer->innerObserver(), nullptr);
+ context = nullptr;
+ Heap::collectAllGarbage();
+ EXPECT_EQ(observer->lifecycleContext(), static_cast<DummyContext*>(0));
+ EXPECT_TRUE(observer->contextDestroyedCalled());
}
+
+} // namespace blink
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698