| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/memory/ref_counted.h" | 10 #include "base/memory/ref_counted.h" |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 54 : list_(list), doomed_(doomed) { } | 54 : list_(list), doomed_(doomed) { } |
| 55 virtual ~ThreadSafeDisrupter() { } | 55 virtual ~ThreadSafeDisrupter() { } |
| 56 virtual void Observe(int x) { | 56 virtual void Observe(int x) { |
| 57 list_->RemoveObserver(doomed_); | 57 list_->RemoveObserver(doomed_); |
| 58 } | 58 } |
| 59 private: | 59 private: |
| 60 ObserverListThreadSafe<Foo>* list_; | 60 ObserverListThreadSafe<Foo>* list_; |
| 61 Foo* doomed_; | 61 Foo* doomed_; |
| 62 }; | 62 }; |
| 63 | 63 |
| 64 template <typename ObserverListType> |
| 64 class AddInObserve : public Foo { | 65 class AddInObserve : public Foo { |
| 65 public: | 66 public: |
| 66 explicit AddInObserve(ObserverList<Foo>* observer_list) | 67 explicit AddInObserve(ObserverListType* observer_list) |
| 67 : added(false), | 68 : added(false), |
| 68 observer_list(observer_list), | 69 observer_list(observer_list), |
| 69 adder(1) { | 70 adder(1) { |
| 70 } | 71 } |
| 71 virtual void Observe(int x) { | 72 virtual void Observe(int x) { |
| 72 if (!added) { | 73 if (!added) { |
| 73 added = true; | 74 added = true; |
| 74 observer_list->AddObserver(&adder); | 75 observer_list->AddObserver(&adder); |
| 75 } | 76 } |
| 76 } | 77 } |
| 77 | 78 |
| 78 bool added; | 79 bool added; |
| 79 ObserverList<Foo>* observer_list; | 80 ObserverListType* observer_list; |
| 80 Adder adder; | 81 Adder adder; |
| 81 }; | 82 }; |
| 82 | 83 |
| 83 | 84 |
| 84 class ObserverListThreadSafeTest : public testing::Test { | |
| 85 }; | |
| 86 | |
| 87 static const int kThreadRunTime = 2000; // ms to run the multi-threaded test. | 85 static const int kThreadRunTime = 2000; // ms to run the multi-threaded test. |
| 88 | 86 |
| 89 // A thread for use in the ThreadSafeObserver test | 87 // A thread for use in the ThreadSafeObserver test |
| 90 // which will add and remove itself from the notification | 88 // which will add and remove itself from the notification |
| 91 // list repeatedly. | 89 // list repeatedly. |
| 92 class AddRemoveThread : public PlatformThread::Delegate, | 90 class AddRemoveThread : public PlatformThread::Delegate, |
| 93 public Foo { | 91 public Foo { |
| 94 public: | 92 public: |
| 95 AddRemoveThread(ObserverListThreadSafe<Foo>* list, bool notify) | 93 AddRemoveThread(ObserverListThreadSafe<Foo>* list, bool notify) |
| 96 : list_(list), | 94 : list_(list), |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 350 // the main thread. | 348 // the main thread. |
| 351 ThreadSafeObserverHarness(7, false); | 349 ThreadSafeObserverHarness(7, false); |
| 352 } | 350 } |
| 353 | 351 |
| 354 TEST(ObserverListThreadSafeTest, CrossThreadNotifications) { | 352 TEST(ObserverListThreadSafeTest, CrossThreadNotifications) { |
| 355 // Use 3 observer threads. Notifications will fire from | 353 // Use 3 observer threads. Notifications will fire from |
| 356 // the main thread and all 3 observer threads. | 354 // the main thread and all 3 observer threads. |
| 357 ThreadSafeObserverHarness(3, true); | 355 ThreadSafeObserverHarness(3, true); |
| 358 } | 356 } |
| 359 | 357 |
| 358 TEST(ObserverListThreadSafeTest, OutlivesMessageLoop) { |
| 359 MessageLoop* loop = new MessageLoop; |
| 360 scoped_refptr<ObserverListThreadSafe<Foo> > observer_list( |
| 361 new ObserverListThreadSafe<Foo>); |
| 362 |
| 363 Adder a(1); |
| 364 observer_list->AddObserver(&a); |
| 365 delete loop; |
| 366 // Test passes if we don't crash here. |
| 367 observer_list->Notify(&Foo::Observe, 1); |
| 368 } |
| 369 |
| 360 TEST(ObserverListTest, Existing) { | 370 TEST(ObserverListTest, Existing) { |
| 361 ObserverList<Foo> observer_list(ObserverList<Foo>::NOTIFY_EXISTING_ONLY); | 371 ObserverList<Foo> observer_list(ObserverList<Foo>::NOTIFY_EXISTING_ONLY); |
| 362 Adder a(1); | 372 Adder a(1); |
| 363 AddInObserve b(&observer_list); | 373 AddInObserve<ObserverList<Foo> > b(&observer_list); |
| 364 | 374 |
| 365 observer_list.AddObserver(&a); | 375 observer_list.AddObserver(&a); |
| 366 observer_list.AddObserver(&b); | 376 observer_list.AddObserver(&b); |
| 367 | 377 |
| 368 FOR_EACH_OBSERVER(Foo, observer_list, Observe(1)); | 378 FOR_EACH_OBSERVER(Foo, observer_list, Observe(1)); |
| 369 | 379 |
| 370 EXPECT_TRUE(b.added); | 380 EXPECT_TRUE(b.added); |
| 371 // B's adder should not have been notified because it was added during | 381 // B's adder should not have been notified because it was added during |
| 372 // notificaiton. | 382 // notificaiton. |
| 373 EXPECT_EQ(0, b.adder.total); | 383 EXPECT_EQ(0, b.adder.total); |
| 374 | 384 |
| 375 // Notify again to make sure b's adder is notified. | 385 // Notify again to make sure b's adder is notified. |
| 376 FOR_EACH_OBSERVER(Foo, observer_list, Observe(1)); | 386 FOR_EACH_OBSERVER(Foo, observer_list, Observe(1)); |
| 377 EXPECT_EQ(1, b.adder.total); | 387 EXPECT_EQ(1, b.adder.total); |
| 378 } | 388 } |
| 379 | 389 |
| 390 // Same as above, but for ObserverListThreadSafe |
| 391 TEST(ObserverListThreadSafeTest, Existing) { |
| 392 MessageLoop loop; |
| 393 scoped_refptr<ObserverListThreadSafe<Foo> > observer_list( |
| 394 new ObserverListThreadSafe<Foo>(ObserverList<Foo>::NOTIFY_EXISTING_ONLY)); |
| 395 Adder a(1); |
| 396 AddInObserve<ObserverListThreadSafe<Foo> > b(observer_list.get()); |
| 397 |
| 398 observer_list->AddObserver(&a); |
| 399 observer_list->AddObserver(&b); |
| 400 |
| 401 observer_list->Notify(&Foo::Observe, 1); |
| 402 loop.RunAllPending(); |
| 403 |
| 404 EXPECT_TRUE(b.added); |
| 405 // B's adder should not have been notified because it was added during |
| 406 // notificaiton. |
| 407 EXPECT_EQ(0, b.adder.total); |
| 408 |
| 409 // Notify again to make sure b's adder is notified. |
| 410 observer_list->Notify(&Foo::Observe, 1); |
| 411 loop.RunAllPending(); |
| 412 EXPECT_EQ(1, b.adder.total); |
| 413 } |
| 414 |
| 380 class AddInClearObserve : public Foo { | 415 class AddInClearObserve : public Foo { |
| 381 public: | 416 public: |
| 382 explicit AddInClearObserve(ObserverList<Foo>* list) | 417 explicit AddInClearObserve(ObserverList<Foo>* list) |
| 383 : list_(list), added_(false), adder_(1) {} | 418 : list_(list), added_(false), adder_(1) {} |
| 384 | 419 |
| 385 virtual void Observe(int /* x */) { | 420 virtual void Observe(int /* x */) { |
| 386 list_->Clear(); | 421 list_->Clear(); |
| 387 list_->AddObserver(&adder_); | 422 list_->AddObserver(&adder_); |
| 388 added_ = true; | 423 added_ = true; |
| 389 } | 424 } |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 439 ObserverList<Foo>* observer_list = new ObserverList<Foo>; | 474 ObserverList<Foo>* observer_list = new ObserverList<Foo>; |
| 440 ListDestructor a(observer_list); | 475 ListDestructor a(observer_list); |
| 441 observer_list->AddObserver(&a); | 476 observer_list->AddObserver(&a); |
| 442 | 477 |
| 443 FOR_EACH_OBSERVER(Foo, *observer_list, Observe(0)); | 478 FOR_EACH_OBSERVER(Foo, *observer_list, Observe(0)); |
| 444 // If this test fails, there'll be Valgrind errors when this function goes out | 479 // If this test fails, there'll be Valgrind errors when this function goes out |
| 445 // of scope. | 480 // of scope. |
| 446 } | 481 } |
| 447 | 482 |
| 448 } // namespace | 483 } // namespace |
| OLD | NEW |