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 |