| 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 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 100 count_addtask_(0), | 100 count_addtask_(0), |
| 101 do_notifies_(notify) { | 101 do_notifies_(notify) { |
| 102 factory_ = new ScopedRunnableMethodFactory<AddRemoveThread>(this); | 102 factory_ = new ScopedRunnableMethodFactory<AddRemoveThread>(this); |
| 103 } | 103 } |
| 104 | 104 |
| 105 virtual ~AddRemoveThread() { | 105 virtual ~AddRemoveThread() { |
| 106 delete factory_; | 106 delete factory_; |
| 107 } | 107 } |
| 108 | 108 |
| 109 void ThreadMain() { | 109 void ThreadMain() { |
| 110 loop_ = new MessageLoop(); // Fire up a message loop. | 110 loop_ = new MessageLoop("ThreadMain"); // Fire up a message loop. |
| 111 loop_->PostTask( | 111 loop_->PostTask( |
| 112 FROM_HERE, factory_->NewRunnableMethod(&AddRemoveThread::AddTask)); | 112 FROM_HERE, factory_->NewRunnableMethod(&AddRemoveThread::AddTask)); |
| 113 loop_->Run(); | 113 loop_->Run(); |
| 114 //LOG(ERROR) << "Loop 0x" << std::hex << loop_ << " done. " << | 114 //LOG(ERROR) << "Loop 0x" << std::hex << loop_ << " done. " << |
| 115 // count_observes_ << ", " << count_addtask_; | 115 // count_observes_ << ", " << count_addtask_; |
| 116 delete loop_; | 116 delete loop_; |
| 117 loop_ = reinterpret_cast<MessageLoop*>(0xdeadbeef); | 117 loop_ = reinterpret_cast<MessageLoop*>(0xdeadbeef); |
| 118 delete this; | 118 delete this; |
| 119 } | 119 } |
| 120 | 120 |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 193 FOR_EACH_OBSERVER(Foo, observer_list, Observe(10)); | 193 FOR_EACH_OBSERVER(Foo, observer_list, Observe(10)); |
| 194 | 194 |
| 195 EXPECT_EQ(a.total, 20); | 195 EXPECT_EQ(a.total, 20); |
| 196 EXPECT_EQ(b.total, -20); | 196 EXPECT_EQ(b.total, -20); |
| 197 EXPECT_EQ(c.total, 0); | 197 EXPECT_EQ(c.total, 0); |
| 198 EXPECT_EQ(d.total, -10); | 198 EXPECT_EQ(d.total, -10); |
| 199 EXPECT_EQ(e.total, 0); | 199 EXPECT_EQ(e.total, 0); |
| 200 } | 200 } |
| 201 | 201 |
| 202 TEST(ObserverListThreadSafeTest, BasicTest) { | 202 TEST(ObserverListThreadSafeTest, BasicTest) { |
| 203 MessageLoop loop; | 203 MessageLoop loop("ObserverListThreadSafeTest"); |
| 204 | 204 |
| 205 scoped_refptr<ObserverListThreadSafe<Foo> > observer_list( | 205 scoped_refptr<ObserverListThreadSafe<Foo> > observer_list( |
| 206 new ObserverListThreadSafe<Foo>); | 206 new ObserverListThreadSafe<Foo>); |
| 207 Adder a(1); | 207 Adder a(1); |
| 208 Adder b(-1); | 208 Adder b(-1); |
| 209 Adder c(1); | 209 Adder c(1); |
| 210 Adder d(-1); | 210 Adder d(-1); |
| 211 ThreadSafeDisrupter evil(observer_list.get(), &c); | 211 ThreadSafeDisrupter evil(observer_list.get(), &c); |
| 212 | 212 |
| 213 observer_list->AddObserver(&a); | 213 observer_list->AddObserver(&a); |
| 214 observer_list->AddObserver(&b); | 214 observer_list->AddObserver(&b); |
| 215 | 215 |
| 216 observer_list->Notify(&Foo::Observe, 10); | 216 observer_list->Notify(&Foo::Observe, 10); |
| 217 loop.RunAllPending(); | 217 loop.RunAllPending(); |
| 218 | 218 |
| 219 observer_list->AddObserver(&evil); | 219 observer_list->AddObserver(&evil); |
| 220 observer_list->AddObserver(&c); | 220 observer_list->AddObserver(&c); |
| 221 observer_list->AddObserver(&d); | 221 observer_list->AddObserver(&d); |
| 222 | 222 |
| 223 observer_list->Notify(&Foo::Observe, 10); | 223 observer_list->Notify(&Foo::Observe, 10); |
| 224 loop.RunAllPending(); | 224 loop.RunAllPending(); |
| 225 | 225 |
| 226 EXPECT_EQ(a.total, 20); | 226 EXPECT_EQ(a.total, 20); |
| 227 EXPECT_EQ(b.total, -20); | 227 EXPECT_EQ(b.total, -20); |
| 228 EXPECT_EQ(c.total, 0); | 228 EXPECT_EQ(c.total, 0); |
| 229 EXPECT_EQ(d.total, -10); | 229 EXPECT_EQ(d.total, -10); |
| 230 } | 230 } |
| 231 | 231 |
| 232 TEST(ObserverListThreadSafeTest, RemoveObserver) { | 232 TEST(ObserverListThreadSafeTest, RemoveObserver) { |
| 233 MessageLoop loop; | 233 MessageLoop loop("ObserverListThreadSafeTest"); |
| 234 | 234 |
| 235 scoped_refptr<ObserverListThreadSafe<Foo> > observer_list( | 235 scoped_refptr<ObserverListThreadSafe<Foo> > observer_list( |
| 236 new ObserverListThreadSafe<Foo>); | 236 new ObserverListThreadSafe<Foo>); |
| 237 Adder a(1), b(1); | 237 Adder a(1), b(1); |
| 238 | 238 |
| 239 // Should do nothing. | 239 // Should do nothing. |
| 240 observer_list->RemoveObserver(&a); | 240 observer_list->RemoveObserver(&a); |
| 241 observer_list->RemoveObserver(&b); | 241 observer_list->RemoveObserver(&b); |
| 242 | 242 |
| 243 observer_list->Notify(&Foo::Observe, 10); | 243 observer_list->Notify(&Foo::Observe, 10); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 275 list_->RemoveObserver(*it); | 275 list_->RemoveObserver(*it); |
| 276 } | 276 } |
| 277 } | 277 } |
| 278 | 278 |
| 279 private: | 279 private: |
| 280 const scoped_refptr<ObserverListThreadSafe<Foo> > list_; | 280 const scoped_refptr<ObserverListThreadSafe<Foo> > list_; |
| 281 std::vector<Foo*> foos_; | 281 std::vector<Foo*> foos_; |
| 282 }; | 282 }; |
| 283 | 283 |
| 284 TEST(ObserverListThreadSafeTest, RemoveMultipleObservers) { | 284 TEST(ObserverListThreadSafeTest, RemoveMultipleObservers) { |
| 285 MessageLoop loop; | 285 MessageLoop loop("ObserverListThreadSafeTest"); |
| 286 scoped_refptr<ObserverListThreadSafe<Foo> > observer_list( | 286 scoped_refptr<ObserverListThreadSafe<Foo> > observer_list( |
| 287 new ObserverListThreadSafe<Foo>); | 287 new ObserverListThreadSafe<Foo>); |
| 288 | 288 |
| 289 FooRemover a(observer_list); | 289 FooRemover a(observer_list); |
| 290 Adder b(1); | 290 Adder b(1); |
| 291 | 291 |
| 292 observer_list->AddObserver(&a); | 292 observer_list->AddObserver(&a); |
| 293 observer_list->AddObserver(&b); | 293 observer_list->AddObserver(&b); |
| 294 | 294 |
| 295 a.AddFooToRemove(&a); | 295 a.AddFooToRemove(&a); |
| 296 a.AddFooToRemove(&b); | 296 a.AddFooToRemove(&b); |
| 297 | 297 |
| 298 observer_list->Notify(&Foo::Observe, 1); | 298 observer_list->Notify(&Foo::Observe, 1); |
| 299 loop.RunAllPending(); | 299 loop.RunAllPending(); |
| 300 } | 300 } |
| 301 | 301 |
| 302 // A test driver for a multi-threaded notification loop. Runs a number | 302 // A test driver for a multi-threaded notification loop. Runs a number |
| 303 // of observer threads, each of which constantly adds/removes itself | 303 // of observer threads, each of which constantly adds/removes itself |
| 304 // from the observer list. Optionally, if cross_thread_notifies is set | 304 // from the observer list. Optionally, if cross_thread_notifies is set |
| 305 // to true, the observer threads will also trigger notifications to | 305 // to true, the observer threads will also trigger notifications to |
| 306 // all observers. | 306 // all observers. |
| 307 static void ThreadSafeObserverHarness(int num_threads, | 307 static void ThreadSafeObserverHarness(int num_threads, |
| 308 bool cross_thread_notifies) { | 308 bool cross_thread_notifies) { |
| 309 MessageLoop loop; | 309 MessageLoop loop("ThreadSafeObserverHarness"); |
| 310 | 310 |
| 311 const int kMaxThreads = 15; | 311 const int kMaxThreads = 15; |
| 312 num_threads = num_threads > kMaxThreads ? kMaxThreads : num_threads; | 312 num_threads = num_threads > kMaxThreads ? kMaxThreads : num_threads; |
| 313 | 313 |
| 314 scoped_refptr<ObserverListThreadSafe<Foo> > observer_list( | 314 scoped_refptr<ObserverListThreadSafe<Foo> > observer_list( |
| 315 new ObserverListThreadSafe<Foo>); | 315 new ObserverListThreadSafe<Foo>); |
| 316 Adder a(1); | 316 Adder a(1); |
| 317 Adder b(-1); | 317 Adder b(-1); |
| 318 Adder c(1); | 318 Adder c(1); |
| 319 Adder d(-1); | 319 Adder d(-1); |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 439 ObserverList<Foo>* observer_list = new ObserverList<Foo>; | 439 ObserverList<Foo>* observer_list = new ObserverList<Foo>; |
| 440 ListDestructor a(observer_list); | 440 ListDestructor a(observer_list); |
| 441 observer_list->AddObserver(&a); | 441 observer_list->AddObserver(&a); |
| 442 | 442 |
| 443 FOR_EACH_OBSERVER(Foo, *observer_list, Observe(0)); | 443 FOR_EACH_OBSERVER(Foo, *observer_list, Observe(0)); |
| 444 // If this test fails, there'll be Valgrind errors when this function goes out | 444 // If this test fails, there'll be Valgrind errors when this function goes out |
| 445 // of scope. | 445 // of scope. |
| 446 } | 446 } |
| 447 | 447 |
| 448 } // namespace | 448 } // namespace |
| OLD | NEW |