Index: base/observer_list_unittest.cc |
diff --git a/base/observer_list_unittest.cc b/base/observer_list_unittest.cc |
index 653d8818b3bb4d1dc81a075064def3373f8e32d1..c5e556bd9da4e76f65ad9965fb256d02932e672b 100644 |
--- a/base/observer_list_unittest.cc |
+++ b/base/observer_list_unittest.cc |
@@ -5,18 +5,13 @@ |
#include "base/observer_list.h" |
#include "base/observer_list_threadsafe.h" |
-#include <utility> |
#include <vector> |
-#include "base/bind.h" |
#include "base/compiler_specific.h" |
#include "base/location.h" |
#include "base/memory/weak_ptr.h" |
#include "base/run_loop.h" |
-#include "base/sequenced_task_runner.h" |
#include "base/single_thread_task_runner.h" |
-#include "base/task_scheduler/post_task.h" |
-#include "base/test/scoped_task_scheduler.h" |
#include "base/threading/platform_thread.h" |
#include "testing/gtest/include/gtest/gtest.h" |
@@ -68,6 +63,20 @@ |
ObserverList<Foo>* list_; |
Foo* doomed_; |
bool remove_self_; |
+}; |
+ |
+class ThreadSafeDisrupter : public Foo { |
+ public: |
+ ThreadSafeDisrupter(ObserverListThreadSafe<Foo>* list, Foo* doomed) |
+ : list_(list), |
+ doomed_(doomed) { |
+ } |
+ ~ThreadSafeDisrupter() override {} |
+ void Observe(int x) override { list_->RemoveObserver(doomed_); } |
+ |
+ private: |
+ ObserverListThreadSafe<Foo>* list_; |
+ Foo* doomed_; |
}; |
template <typename ObserverListType> |
@@ -267,6 +276,7 @@ |
Adder b(-1); |
Adder c(1); |
Adder d(-1); |
+ ThreadSafeDisrupter evil(observer_list.get(), &c); |
observer_list->AddObserver(&a); |
observer_list->AddObserver(&b); |
@@ -274,11 +284,11 @@ |
observer_list->Notify(FROM_HERE, &Foo::Observe, 10); |
RunLoop().RunUntilIdle(); |
+ observer_list->AddObserver(&evil); |
observer_list->AddObserver(&c); |
observer_list->AddObserver(&d); |
observer_list->Notify(FROM_HERE, &Foo::Observe, 10); |
- observer_list->RemoveObserver(&c); |
RunLoop().RunUntilIdle(); |
EXPECT_EQ(20, a.total); |
@@ -319,18 +329,18 @@ |
EXPECT_EQ(0, b.total); |
} |
-TEST(ObserverListThreadSafeTest, WithoutSequence) { |
+TEST(ObserverListThreadSafeTest, WithoutMessageLoop) { |
scoped_refptr<ObserverListThreadSafe<Foo> > observer_list( |
new ObserverListThreadSafe<Foo>); |
Adder a(1), b(1), c(1); |
- // No sequence, so these should not be added. |
+ // No MessageLoop, so these should not be added. |
observer_list->AddObserver(&a); |
observer_list->AddObserver(&b); |
{ |
- // Add c when there's a sequence. |
+ // Add c when there's a loop. |
MessageLoop loop; |
observer_list->AddObserver(&c); |
@@ -341,10 +351,10 @@ |
EXPECT_EQ(0, b.total); |
EXPECT_EQ(10, c.total); |
- // Now add a when there's a sequence. |
+ // Now add a when there's a loop. |
observer_list->AddObserver(&a); |
- // Remove c when there's a sequence. |
+ // Remove c when there's a loop. |
observer_list->RemoveObserver(&c); |
// Notify again. |
@@ -356,7 +366,7 @@ |
EXPECT_EQ(10, c.total); |
} |
- // Removing should always succeed with or without a sequence. |
+ // Removing should always succeed with or without a loop. |
observer_list->RemoveObserver(&a); |
// Notifying should not fail but should also be a no-op. |
@@ -479,79 +489,6 @@ |
delete loop; |
// Test passes if we don't crash here. |
observer_list->Notify(FROM_HERE, &Foo::Observe, 1); |
-} |
- |
-namespace { |
- |
-class SequenceVerificationObserver : public Foo { |
- public: |
- explicit SequenceVerificationObserver( |
- scoped_refptr<SequencedTaskRunner> task_runner) |
- : task_runner_(std::move(task_runner)) {} |
- ~SequenceVerificationObserver() override = default; |
- |
- void Observe(int x) override { |
- called_on_valid_sequence_ = task_runner_->RunsTasksOnCurrentThread(); |
- } |
- |
- bool called_on_valid_sequence() const { return called_on_valid_sequence_; } |
- |
- private: |
- const scoped_refptr<SequencedTaskRunner> task_runner_; |
- bool called_on_valid_sequence_ = false; |
- |
- DISALLOW_COPY_AND_ASSIGN(SequenceVerificationObserver); |
-}; |
- |
-} // namespace |
- |
-// Verify that observers are notified on the correct sequence. |
-TEST(ObserverListThreadSafeTest, NotificationOnValidSequence) { |
- test::ScopedTaskScheduler scoped_task_scheduler; |
- |
- auto task_runner_1 = CreateSequencedTaskRunnerWithTraits(TaskTraits()); |
- auto task_runner_2 = CreateSequencedTaskRunnerWithTraits(TaskTraits()); |
- |
- auto observer_list = make_scoped_refptr(new ObserverListThreadSafe<Foo>()); |
- |
- SequenceVerificationObserver observer_1(task_runner_1); |
- SequenceVerificationObserver observer_2(task_runner_2); |
- |
- task_runner_1->PostTask( |
- FROM_HERE, Bind(&ObserverListThreadSafe<Foo>::AddObserver, observer_list, |
- Unretained(&observer_1))); |
- task_runner_2->PostTask( |
- FROM_HERE, Bind(&ObserverListThreadSafe<Foo>::AddObserver, observer_list, |
- Unretained(&observer_2))); |
- |
- RunLoop().RunUntilIdle(); |
- |
- observer_list->Notify(FROM_HERE, &Foo::Observe, 1); |
- |
- RunLoop().RunUntilIdle(); |
- |
- EXPECT_TRUE(observer_1.called_on_valid_sequence()); |
- EXPECT_TRUE(observer_2.called_on_valid_sequence()); |
-} |
- |
-// Verify that when an observer is added to a NOTIFY_ALL ObserverListThreadSafe |
-// from a notification, it is itself notified. |
-TEST(ObserverListThreadSafeTest, AddObserverFromNotificationNotifyAll) { |
- MessageLoop message_loop; |
- auto observer_list = make_scoped_refptr(new ObserverListThreadSafe<Foo>()); |
- |
- Adder observer_added_from_notification(1); |
- |
- AddInObserve<ObserverListThreadSafe<Foo>> initial_observer( |
- observer_list.get()); |
- initial_observer.SetToAdd(&observer_added_from_notification); |
- observer_list->AddObserver(&initial_observer); |
- |
- observer_list->Notify(FROM_HERE, &Foo::Observe, 1); |
- |
- RunLoop().RunUntilIdle(); |
- |
- EXPECT_EQ(1, observer_added_from_notification.GetValue()); |
} |
TEST(ObserverListTest, Existing) { |