OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/observer_list.h" | 5 #include "base/observer_list.h" |
6 #include "base/observer_list_threadsafe.h" | 6 #include "base/observer_list_threadsafe.h" |
7 | 7 |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
11 #include "base/location.h" | 11 #include "base/location.h" |
12 #include "base/memory/weak_ptr.h" | 12 #include "base/memory/weak_ptr.h" |
13 #include "base/run_loop.h" | 13 #include "base/run_loop.h" |
14 #include "base/single_thread_task_runner.h" | 14 #include "base/single_thread_task_runner.h" |
15 #include "base/threading/platform_thread.h" | 15 #include "base/threading/platform_thread.h" |
16 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
17 | 17 |
18 namespace base { | 18 namespace base { |
19 namespace { | 19 namespace { |
20 | 20 |
21 class Foo { | 21 class Foo { |
22 public: | 22 public: |
23 virtual void Observe(int x) = 0; | 23 virtual void Observe(int x) = 0; |
24 virtual ~Foo() {} | 24 virtual ~Foo() {} |
| 25 virtual int GetValue() const { return 0; } |
25 }; | 26 }; |
26 | 27 |
27 class Adder : public Foo { | 28 class Adder : public Foo { |
28 public: | 29 public: |
29 explicit Adder(int scaler) : total(0), scaler_(scaler) {} | 30 explicit Adder(int scaler) : total(0), scaler_(scaler) {} |
| 31 ~Adder() override {} |
| 32 |
30 void Observe(int x) override { total += x * scaler_; } | 33 void Observe(int x) override { total += x * scaler_; } |
31 ~Adder() override {} | 34 int GetValue() const override { return total; } |
| 35 |
32 int total; | 36 int total; |
33 | 37 |
34 private: | 38 private: |
35 int scaler_; | 39 int scaler_; |
36 }; | 40 }; |
37 | 41 |
38 class Disrupter : public Foo { | 42 class Disrupter : public Foo { |
39 public: | 43 public: |
40 Disrupter(ObserverList<Foo>* list, Foo* doomed) | 44 Disrupter(ObserverList<Foo>* list, Foo* doomed) |
41 : list_(list), | 45 : list_(list), |
42 doomed_(doomed) { | 46 doomed_(doomed) { |
43 } | 47 } |
44 ~Disrupter() override {} | 48 ~Disrupter() override {} |
45 void Observe(int x) override { list_->RemoveObserver(doomed_); } | 49 void Observe(int x) override { list_->RemoveObserver(doomed_); } |
46 | 50 |
47 private: | 51 private: |
48 ObserverList<Foo>* list_; | 52 ObserverList<Foo>* list_; |
49 Foo* doomed_; | 53 Foo* doomed_; |
50 }; | 54 }; |
51 | 55 |
| 56 class DisrupterSelf : public Foo { |
| 57 public: |
| 58 DisrupterSelf(ObserverList<Foo>* list) : list_(list) {} |
| 59 ~DisrupterSelf() override {} |
| 60 void Observe(int x) override { list_->RemoveObserver(this); } |
| 61 |
| 62 private: |
| 63 ObserverList<Foo>* list_; |
| 64 }; |
| 65 |
52 class ThreadSafeDisrupter : public Foo { | 66 class ThreadSafeDisrupter : public Foo { |
53 public: | 67 public: |
54 ThreadSafeDisrupter(ObserverListThreadSafe<Foo>* list, Foo* doomed) | 68 ThreadSafeDisrupter(ObserverListThreadSafe<Foo>* list, Foo* doomed) |
55 : list_(list), | 69 : list_(list), |
56 doomed_(doomed) { | 70 doomed_(doomed) { |
57 } | 71 } |
58 ~ThreadSafeDisrupter() override {} | 72 ~ThreadSafeDisrupter() override {} |
59 void Observe(int x) override { list_->RemoveObserver(doomed_); } | 73 void Observe(int x) override { list_->RemoveObserver(doomed_); } |
60 | 74 |
61 private: | 75 private: |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
198 | 212 |
199 FOR_EACH_OBSERVER(Foo, observer_list, Observe(10)); | 213 FOR_EACH_OBSERVER(Foo, observer_list, Observe(10)); |
200 | 214 |
201 EXPECT_EQ(20, a.total); | 215 EXPECT_EQ(20, a.total); |
202 EXPECT_EQ(-20, b.total); | 216 EXPECT_EQ(-20, b.total); |
203 EXPECT_EQ(0, c.total); | 217 EXPECT_EQ(0, c.total); |
204 EXPECT_EQ(-10, d.total); | 218 EXPECT_EQ(-10, d.total); |
205 EXPECT_EQ(0, e.total); | 219 EXPECT_EQ(0, e.total); |
206 } | 220 } |
207 | 221 |
| 222 TEST(ObserverListTest, DesruptSelf) { |
| 223 ObserverList<Foo> observer_list; |
| 224 Adder a(1), b(-1), c(1), d(-1); |
| 225 DisrupterSelf evil(&observer_list); |
| 226 |
| 227 observer_list.AddObserver(&a); |
| 228 observer_list.AddObserver(&b); |
| 229 |
| 230 FOR_EACH_OBSERVER(Foo, observer_list, Observe(10)); |
| 231 |
| 232 observer_list.AddObserver(&evil); |
| 233 observer_list.AddObserver(&c); |
| 234 observer_list.AddObserver(&d); |
| 235 |
| 236 FOR_EACH_OBSERVER(Foo, observer_list, Observe(10)); |
| 237 |
| 238 EXPECT_EQ(20, a.total); |
| 239 EXPECT_EQ(-20, b.total); |
| 240 EXPECT_EQ(10, c.total); |
| 241 EXPECT_EQ(-10, d.total); |
| 242 } |
| 243 |
| 244 TEST(ObserverListTest, DesruptBefore) { |
| 245 ObserverList<Foo> observer_list; |
| 246 Adder a(1), b(-1), c(1), d(-1); |
| 247 Disrupter evil(&observer_list, &b); |
| 248 |
| 249 observer_list.AddObserver(&a); |
| 250 observer_list.AddObserver(&b); |
| 251 observer_list.AddObserver(&evil); |
| 252 observer_list.AddObserver(&c); |
| 253 observer_list.AddObserver(&d); |
| 254 |
| 255 FOR_EACH_OBSERVER(Foo, observer_list, Observe(10)); |
| 256 FOR_EACH_OBSERVER(Foo, observer_list, Observe(10)); |
| 257 |
| 258 EXPECT_EQ(20, a.total); |
| 259 EXPECT_EQ(-10, b.total); |
| 260 EXPECT_EQ(20, c.total); |
| 261 EXPECT_EQ(-20, d.total); |
| 262 } |
| 263 |
208 TEST(ObserverListThreadSafeTest, BasicTest) { | 264 TEST(ObserverListThreadSafeTest, BasicTest) { |
209 MessageLoop loop; | 265 MessageLoop loop; |
210 | 266 |
211 scoped_refptr<ObserverListThreadSafe<Foo> > observer_list( | 267 scoped_refptr<ObserverListThreadSafe<Foo> > observer_list( |
212 new ObserverListThreadSafe<Foo>); | 268 new ObserverListThreadSafe<Foo>); |
213 Adder a(1); | 269 Adder a(1); |
214 Adder b(-1); | 270 Adder b(-1); |
215 Adder c(1); | 271 Adder c(1); |
216 Adder d(-1); | 272 Adder d(-1); |
217 ThreadSafeDisrupter evil(observer_list.get(), &c); | 273 ThreadSafeDisrupter evil(observer_list.get(), &c); |
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
534 TEST(ObserverListTest, IteratorOutlivesList) { | 590 TEST(ObserverListTest, IteratorOutlivesList) { |
535 ObserverList<Foo>* observer_list = new ObserverList<Foo>; | 591 ObserverList<Foo>* observer_list = new ObserverList<Foo>; |
536 ListDestructor a(observer_list); | 592 ListDestructor a(observer_list); |
537 observer_list->AddObserver(&a); | 593 observer_list->AddObserver(&a); |
538 | 594 |
539 FOR_EACH_OBSERVER(Foo, *observer_list, Observe(0)); | 595 FOR_EACH_OBSERVER(Foo, *observer_list, Observe(0)); |
540 // If this test fails, there'll be Valgrind errors when this function goes out | 596 // If this test fails, there'll be Valgrind errors when this function goes out |
541 // of scope. | 597 // of scope. |
542 } | 598 } |
543 | 599 |
| 600 TEST(ObserverListTest, BasicStdIterator) { |
| 601 using FooList = ObserverList<Foo>; |
| 602 FooList observer_list; |
| 603 |
| 604 // Iterate over empty list: no effect, no crash. |
| 605 for (auto& i : observer_list) |
| 606 i.Observe(10); |
| 607 |
| 608 Adder a(1), b(-1), c(1), d(-1); |
| 609 |
| 610 observer_list.AddObserver(&a); |
| 611 observer_list.AddObserver(&b); |
| 612 observer_list.AddObserver(&c); |
| 613 observer_list.AddObserver(&d); |
| 614 |
| 615 for (FooList::iterator i = observer_list.begin(), e = observer_list.end(); |
| 616 i != e; ++i) |
| 617 i->Observe(1); |
| 618 |
| 619 EXPECT_EQ(1, a.total); |
| 620 EXPECT_EQ(-1, b.total); |
| 621 EXPECT_EQ(1, c.total); |
| 622 EXPECT_EQ(-1, d.total); |
| 623 |
| 624 // Check an iteration over a 'const view' for a given container. |
| 625 const FooList& const_list = observer_list; |
| 626 for (FooList::const_iterator i = const_list.begin(), e = const_list.end(); |
| 627 i != e; ++i) { |
| 628 EXPECT_EQ(1, std::abs(i->GetValue())); |
| 629 } |
| 630 |
| 631 for (const auto& o : const_list) |
| 632 EXPECT_EQ(1, std::abs(o.GetValue())); |
| 633 } |
| 634 |
| 635 TEST(ObserverListTest, StdIteratorRemoveItself) { |
| 636 ObserverList<Foo> observer_list; |
| 637 Adder a(1), b(-1), c(1), d(-1); |
| 638 DisrupterSelf disrupter(&observer_list); |
| 639 |
| 640 observer_list.AddObserver(&a); |
| 641 observer_list.AddObserver(&b); |
| 642 observer_list.AddObserver(&disrupter); |
| 643 observer_list.AddObserver(&c); |
| 644 observer_list.AddObserver(&d); |
| 645 |
| 646 for (auto& o : observer_list) |
| 647 o.Observe(1); |
| 648 |
| 649 for (auto& o : observer_list) |
| 650 o.Observe(10); |
| 651 |
| 652 EXPECT_EQ(11, a.total); |
| 653 EXPECT_EQ(-11, b.total); |
| 654 EXPECT_EQ(11, c.total); |
| 655 EXPECT_EQ(-11, d.total); |
| 656 } |
| 657 |
| 658 TEST(ObserverListTest, StdIteratorRemoveBefore) { |
| 659 ObserverList<Foo> observer_list; |
| 660 Adder a(1), b(-1), c(1), d(-1); |
| 661 Disrupter disrupter(&observer_list, &b); |
| 662 |
| 663 observer_list.AddObserver(&a); |
| 664 observer_list.AddObserver(&b); |
| 665 observer_list.AddObserver(&disrupter); |
| 666 observer_list.AddObserver(&c); |
| 667 observer_list.AddObserver(&d); |
| 668 |
| 669 for (auto& o : observer_list) |
| 670 o.Observe(1); |
| 671 |
| 672 for (auto& o : observer_list) |
| 673 o.Observe(10); |
| 674 |
| 675 EXPECT_EQ(11, a.total); |
| 676 EXPECT_EQ(-1, b.total); |
| 677 EXPECT_EQ(11, c.total); |
| 678 EXPECT_EQ(-11, d.total); |
| 679 } |
| 680 |
| 681 TEST(ObserverListTest, StdIteratorRemoveAfter) { |
| 682 ObserverList<Foo> observer_list; |
| 683 Adder a(1), b(-1), c(1), d(-1); |
| 684 Disrupter disrupter(&observer_list, &c); |
| 685 |
| 686 observer_list.AddObserver(&a); |
| 687 observer_list.AddObserver(&b); |
| 688 observer_list.AddObserver(&disrupter); |
| 689 observer_list.AddObserver(&c); |
| 690 observer_list.AddObserver(&d); |
| 691 |
| 692 for (auto& o : observer_list) |
| 693 o.Observe(1); |
| 694 |
| 695 for (auto& o : observer_list) |
| 696 o.Observe(10); |
| 697 |
| 698 EXPECT_EQ(11, a.total); |
| 699 EXPECT_EQ(-11, b.total); |
| 700 EXPECT_EQ(0, c.total); |
| 701 EXPECT_EQ(-11, d.total); |
| 702 } |
| 703 |
| 704 TEST(ObserverListTest, StdIteratorRemoveAfterFront) { |
| 705 ObserverList<Foo> observer_list; |
| 706 Adder a(1), b(-1), c(1), d(-1); |
| 707 Disrupter disrupter(&observer_list, &a); |
| 708 |
| 709 observer_list.AddObserver(&a); |
| 710 observer_list.AddObserver(&disrupter); |
| 711 observer_list.AddObserver(&b); |
| 712 observer_list.AddObserver(&c); |
| 713 observer_list.AddObserver(&d); |
| 714 |
| 715 for (auto& o : observer_list) |
| 716 o.Observe(1); |
| 717 |
| 718 for (auto& o : observer_list) |
| 719 o.Observe(10); |
| 720 |
| 721 EXPECT_EQ(1, a.total); |
| 722 EXPECT_EQ(-11, b.total); |
| 723 EXPECT_EQ(11, c.total); |
| 724 EXPECT_EQ(-11, d.total); |
| 725 } |
| 726 |
| 727 TEST(ObserverListTest, StdIteratorRemoveBeforeBack) { |
| 728 ObserverList<Foo> observer_list; |
| 729 Adder a(1), b(-1), c(1), d(-1); |
| 730 Disrupter disrupter(&observer_list, &d); |
| 731 |
| 732 observer_list.AddObserver(&a); |
| 733 observer_list.AddObserver(&b); |
| 734 observer_list.AddObserver(&c); |
| 735 observer_list.AddObserver(&disrupter); |
| 736 observer_list.AddObserver(&d); |
| 737 |
| 738 for (auto& o : observer_list) |
| 739 o.Observe(1); |
| 740 |
| 741 for (auto& o : observer_list) |
| 742 o.Observe(10); |
| 743 |
| 744 EXPECT_EQ(11, a.total); |
| 745 EXPECT_EQ(-11, b.total); |
| 746 EXPECT_EQ(11, c.total); |
| 747 EXPECT_EQ(0, d.total); |
| 748 } |
| 749 |
| 750 TEST(ObserverListTest, StdIteratorRemoveFront) { |
| 751 ObserverList<Foo> observer_list; |
| 752 Adder a(1), b(-1), c(1), d(-1); |
| 753 DisrupterSelf disrupter(&observer_list); |
| 754 |
| 755 observer_list.AddObserver(&disrupter); |
| 756 observer_list.AddObserver(&a); |
| 757 observer_list.AddObserver(&b); |
| 758 observer_list.AddObserver(&c); |
| 759 observer_list.AddObserver(&d); |
| 760 |
| 761 for (auto& o : observer_list) |
| 762 o.Observe(1); |
| 763 |
| 764 for (auto& o : observer_list) |
| 765 o.Observe(10); |
| 766 |
| 767 EXPECT_EQ(11, a.total); |
| 768 EXPECT_EQ(-11, b.total); |
| 769 EXPECT_EQ(11, c.total); |
| 770 EXPECT_EQ(-11, d.total); |
| 771 } |
| 772 |
| 773 TEST(ObserverListTest, StdIteratorRemoveBack) { |
| 774 ObserverList<Foo> observer_list; |
| 775 Adder a(1), b(-1), c(1), d(-1); |
| 776 DisrupterSelf disrupter(&observer_list); |
| 777 |
| 778 observer_list.AddObserver(&a); |
| 779 observer_list.AddObserver(&b); |
| 780 observer_list.AddObserver(&c); |
| 781 observer_list.AddObserver(&d); |
| 782 observer_list.AddObserver(&disrupter); |
| 783 |
| 784 for (auto& o : observer_list) |
| 785 o.Observe(1); |
| 786 |
| 787 for (auto& o : observer_list) |
| 788 o.Observe(10); |
| 789 |
| 790 EXPECT_EQ(11, a.total); |
| 791 EXPECT_EQ(-11, b.total); |
| 792 EXPECT_EQ(11, c.total); |
| 793 EXPECT_EQ(-11, d.total); |
| 794 } |
| 795 |
544 } // namespace | 796 } // namespace |
545 } // namespace base | 797 } // namespace base |
OLD | NEW |