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

Side by Side Diff: base/observer_list_unittest.cc

Issue 7604006: Use MessageLoopProxy instead of MessageLoop to dispatch notifications in ObserverListThreadsafe. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 4 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
OLDNEW
« base/observer_list_threadsafe.h ('K') | « base/observer_list_threadsafe.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698