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

Side by Side Diff: base/observer_list_unittest.cc

Issue 12226007: base: Convert the remaining uses of MessageLoop::RunUntilIdle to RunLoop variant. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix win Created 7 years, 10 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
« no previous file with comments | « base/metrics/field_trial_unittest.cc ('k') | base/prefs/json_pref_store_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/memory/weak_ptr.h" 11 #include "base/memory/weak_ptr.h"
12 #include "base/message_loop.h" 12 #include "base/message_loop.h"
13 #include "base/run_loop.h"
13 #include "base/threading/platform_thread.h" 14 #include "base/threading/platform_thread.h"
14 #include "testing/gtest/include/gtest/gtest.h" 15 #include "testing/gtest/include/gtest/gtest.h"
15 16
16 using base::PlatformThread; 17 namespace base {
17 using base::Time;
18
19 namespace { 18 namespace {
20 19
21 class Foo { 20 class Foo {
22 public: 21 public:
23 virtual void Observe(int x) = 0; 22 virtual void Observe(int x) = 0;
24 virtual ~Foo() {} 23 virtual ~Foo() {}
25 }; 24 };
26 25
27 class Adder : public Foo { 26 class Adder : public Foo {
28 public: 27 public:
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
216 Adder a(1); 215 Adder a(1);
217 Adder b(-1); 216 Adder b(-1);
218 Adder c(1); 217 Adder c(1);
219 Adder d(-1); 218 Adder d(-1);
220 ThreadSafeDisrupter evil(observer_list.get(), &c); 219 ThreadSafeDisrupter evil(observer_list.get(), &c);
221 220
222 observer_list->AddObserver(&a); 221 observer_list->AddObserver(&a);
223 observer_list->AddObserver(&b); 222 observer_list->AddObserver(&b);
224 223
225 observer_list->Notify(&Foo::Observe, 10); 224 observer_list->Notify(&Foo::Observe, 10);
226 loop.RunUntilIdle(); 225 RunLoop().RunUntilIdle();
227 226
228 observer_list->AddObserver(&evil); 227 observer_list->AddObserver(&evil);
229 observer_list->AddObserver(&c); 228 observer_list->AddObserver(&c);
230 observer_list->AddObserver(&d); 229 observer_list->AddObserver(&d);
231 230
232 observer_list->Notify(&Foo::Observe, 10); 231 observer_list->Notify(&Foo::Observe, 10);
233 loop.RunUntilIdle(); 232 RunLoop().RunUntilIdle();
234 233
235 EXPECT_EQ(20, a.total); 234 EXPECT_EQ(20, a.total);
236 EXPECT_EQ(-20, b.total); 235 EXPECT_EQ(-20, b.total);
237 EXPECT_EQ(0, c.total); 236 EXPECT_EQ(0, c.total);
238 EXPECT_EQ(-10, d.total); 237 EXPECT_EQ(-10, d.total);
239 } 238 }
240 239
241 TEST(ObserverListThreadSafeTest, RemoveObserver) { 240 TEST(ObserverListThreadSafeTest, RemoveObserver) {
242 MessageLoop loop; 241 MessageLoop loop;
243 242
244 scoped_refptr<ObserverListThreadSafe<Foo> > observer_list( 243 scoped_refptr<ObserverListThreadSafe<Foo> > observer_list(
245 new ObserverListThreadSafe<Foo>); 244 new ObserverListThreadSafe<Foo>);
246 Adder a(1), b(1); 245 Adder a(1), b(1);
247 246
248 // A workaround for the compiler bug. See http://crbug.com/121960. 247 // A workaround for the compiler bug. See http://crbug.com/121960.
249 EXPECT_NE(&a, &b); 248 EXPECT_NE(&a, &b);
250 249
251 // Should do nothing. 250 // Should do nothing.
252 observer_list->RemoveObserver(&a); 251 observer_list->RemoveObserver(&a);
253 observer_list->RemoveObserver(&b); 252 observer_list->RemoveObserver(&b);
254 253
255 observer_list->Notify(&Foo::Observe, 10); 254 observer_list->Notify(&Foo::Observe, 10);
256 loop.RunUntilIdle(); 255 RunLoop().RunUntilIdle();
257 256
258 EXPECT_EQ(0, a.total); 257 EXPECT_EQ(0, a.total);
259 EXPECT_EQ(0, b.total); 258 EXPECT_EQ(0, b.total);
260 259
261 observer_list->AddObserver(&a); 260 observer_list->AddObserver(&a);
262 261
263 // Should also do nothing. 262 // Should also do nothing.
264 observer_list->RemoveObserver(&b); 263 observer_list->RemoveObserver(&b);
265 264
266 observer_list->Notify(&Foo::Observe, 10); 265 observer_list->Notify(&Foo::Observe, 10);
267 loop.RunUntilIdle(); 266 RunLoop().RunUntilIdle();
268 267
269 EXPECT_EQ(10, a.total); 268 EXPECT_EQ(10, a.total);
270 EXPECT_EQ(0, b.total); 269 EXPECT_EQ(0, b.total);
271 } 270 }
272 271
273 TEST(ObserverListThreadSafeTest, WithoutMessageLoop) { 272 TEST(ObserverListThreadSafeTest, WithoutMessageLoop) {
274 scoped_refptr<ObserverListThreadSafe<Foo> > observer_list( 273 scoped_refptr<ObserverListThreadSafe<Foo> > observer_list(
275 new ObserverListThreadSafe<Foo>); 274 new ObserverListThreadSafe<Foo>);
276 275
277 Adder a(1), b(1), c(1); 276 Adder a(1), b(1), c(1);
278 277
279 // No MessageLoop, so these should not be added. 278 // No MessageLoop, so these should not be added.
280 observer_list->AddObserver(&a); 279 observer_list->AddObserver(&a);
281 observer_list->AddObserver(&b); 280 observer_list->AddObserver(&b);
282 281
283 { 282 {
284 // Add c when there's a loop. 283 // Add c when there's a loop.
285 MessageLoop loop; 284 MessageLoop loop;
286 observer_list->AddObserver(&c); 285 observer_list->AddObserver(&c);
287 286
288 observer_list->Notify(&Foo::Observe, 10); 287 observer_list->Notify(&Foo::Observe, 10);
289 loop.RunUntilIdle(); 288 RunLoop().RunUntilIdle();
290 289
291 EXPECT_EQ(0, a.total); 290 EXPECT_EQ(0, a.total);
292 EXPECT_EQ(0, b.total); 291 EXPECT_EQ(0, b.total);
293 EXPECT_EQ(10, c.total); 292 EXPECT_EQ(10, c.total);
294 293
295 // Now add a when there's a loop. 294 // Now add a when there's a loop.
296 observer_list->AddObserver(&a); 295 observer_list->AddObserver(&a);
297 296
298 // Remove c when there's a loop. 297 // Remove c when there's a loop.
299 observer_list->RemoveObserver(&c); 298 observer_list->RemoveObserver(&c);
300 299
301 // Notify again. 300 // Notify again.
302 observer_list->Notify(&Foo::Observe, 20); 301 observer_list->Notify(&Foo::Observe, 20);
303 loop.RunUntilIdle(); 302 RunLoop().RunUntilIdle();
304 303
305 EXPECT_EQ(20, a.total); 304 EXPECT_EQ(20, a.total);
306 EXPECT_EQ(0, b.total); 305 EXPECT_EQ(0, b.total);
307 EXPECT_EQ(10, c.total); 306 EXPECT_EQ(10, c.total);
308 } 307 }
309 308
310 // Removing should always succeed with or without a loop. 309 // Removing should always succeed with or without a loop.
311 observer_list->RemoveObserver(&a); 310 observer_list->RemoveObserver(&a);
312 311
313 // Notifying should not fail but should also be a no-op. 312 // Notifying should not fail but should also be a no-op.
314 MessageLoop loop; 313 MessageLoop loop;
315 observer_list->AddObserver(&b); 314 observer_list->AddObserver(&b);
316 observer_list->Notify(&Foo::Observe, 30); 315 observer_list->Notify(&Foo::Observe, 30);
317 loop.RunUntilIdle(); 316 RunLoop().RunUntilIdle();
318 317
319 EXPECT_EQ(20, a.total); 318 EXPECT_EQ(20, a.total);
320 EXPECT_EQ(30, b.total); 319 EXPECT_EQ(30, b.total);
321 EXPECT_EQ(10, c.total); 320 EXPECT_EQ(10, c.total);
322 } 321 }
323 322
324 class FooRemover : public Foo { 323 class FooRemover : public Foo {
325 public: 324 public:
326 explicit FooRemover(ObserverListThreadSafe<Foo>* list) : list_(list) {} 325 explicit FooRemover(ObserverListThreadSafe<Foo>* list) : list_(list) {}
327 virtual ~FooRemover() {} 326 virtual ~FooRemover() {}
(...skipping 24 matching lines...) Expand all
352 FooRemover a(observer_list); 351 FooRemover a(observer_list);
353 Adder b(1); 352 Adder b(1);
354 353
355 observer_list->AddObserver(&a); 354 observer_list->AddObserver(&a);
356 observer_list->AddObserver(&b); 355 observer_list->AddObserver(&b);
357 356
358 a.AddFooToRemove(&a); 357 a.AddFooToRemove(&a);
359 a.AddFooToRemove(&b); 358 a.AddFooToRemove(&b);
360 359
361 observer_list->Notify(&Foo::Observe, 1); 360 observer_list->Notify(&Foo::Observe, 1);
362 loop.RunUntilIdle(); 361 RunLoop().RunUntilIdle();
363 } 362 }
364 363
365 // A test driver for a multi-threaded notification loop. Runs a number 364 // A test driver for a multi-threaded notification loop. Runs a number
366 // of observer threads, each of which constantly adds/removes itself 365 // of observer threads, each of which constantly adds/removes itself
367 // from the observer list. Optionally, if cross_thread_notifies is set 366 // from the observer list. Optionally, if cross_thread_notifies is set
368 // to true, the observer threads will also trigger notifications to 367 // to true, the observer threads will also trigger notifications to
369 // all observers. 368 // all observers.
370 static void ThreadSafeObserverHarness(int num_threads, 369 static void ThreadSafeObserverHarness(int num_threads,
371 bool cross_thread_notifies) { 370 bool cross_thread_notifies) {
372 MessageLoop loop; 371 MessageLoop loop;
(...skipping 19 matching lines...) Expand all
392 threaded_observer[index], &threads[index])); 391 threaded_observer[index], &threads[index]));
393 } 392 }
394 393
395 Time start = Time::Now(); 394 Time start = Time::Now();
396 while (true) { 395 while (true) {
397 if ((Time::Now() - start).InMilliseconds() > kThreadRunTime) 396 if ((Time::Now() - start).InMilliseconds() > kThreadRunTime)
398 break; 397 break;
399 398
400 observer_list->Notify(&Foo::Observe, 10); 399 observer_list->Notify(&Foo::Observe, 10);
401 400
402 loop.RunUntilIdle(); 401 RunLoop().RunUntilIdle();
403 } 402 }
404 403
405 for (int index = 0; index < num_threads; index++) { 404 for (int index = 0; index < num_threads; index++) {
406 threaded_observer[index]->Quit(); 405 threaded_observer[index]->Quit();
407 PlatformThread::Join(threads[index]); 406 PlatformThread::Join(threads[index]);
408 } 407 }
409 } 408 }
410 409
411 TEST(ObserverListThreadSafeTest, CrossThreadObserver) { 410 TEST(ObserverListThreadSafeTest, CrossThreadObserver) {
412 // Use 7 observer threads. Notifications only come from 411 // Use 7 observer threads. Notifications only come from
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 MessageLoop loop; 456 MessageLoop loop;
458 scoped_refptr<ObserverListThreadSafe<Foo> > observer_list( 457 scoped_refptr<ObserverListThreadSafe<Foo> > observer_list(
459 new ObserverListThreadSafe<Foo>(ObserverList<Foo>::NOTIFY_EXISTING_ONLY)); 458 new ObserverListThreadSafe<Foo>(ObserverList<Foo>::NOTIFY_EXISTING_ONLY));
460 Adder a(1); 459 Adder a(1);
461 AddInObserve<ObserverListThreadSafe<Foo> > b(observer_list.get()); 460 AddInObserve<ObserverListThreadSafe<Foo> > b(observer_list.get());
462 461
463 observer_list->AddObserver(&a); 462 observer_list->AddObserver(&a);
464 observer_list->AddObserver(&b); 463 observer_list->AddObserver(&b);
465 464
466 observer_list->Notify(&Foo::Observe, 1); 465 observer_list->Notify(&Foo::Observe, 1);
467 loop.RunUntilIdle(); 466 RunLoop().RunUntilIdle();
468 467
469 EXPECT_TRUE(b.added); 468 EXPECT_TRUE(b.added);
470 // B's adder should not have been notified because it was added during 469 // B's adder should not have been notified because it was added during
471 // notificaiton. 470 // notificaiton.
472 EXPECT_EQ(0, b.adder.total); 471 EXPECT_EQ(0, b.adder.total);
473 472
474 // Notify again to make sure b's adder is notified. 473 // Notify again to make sure b's adder is notified.
475 observer_list->Notify(&Foo::Observe, 1); 474 observer_list->Notify(&Foo::Observe, 1);
476 loop.RunUntilIdle(); 475 RunLoop().RunUntilIdle();
477 EXPECT_EQ(1, b.adder.total); 476 EXPECT_EQ(1, b.adder.total);
478 } 477 }
479 478
480 class AddInClearObserve : public Foo { 479 class AddInClearObserve : public Foo {
481 public: 480 public:
482 explicit AddInClearObserve(ObserverList<Foo>* list) 481 explicit AddInClearObserve(ObserverList<Foo>* list)
483 : list_(list), added_(false), adder_(1) {} 482 : list_(list), added_(false), adder_(1) {}
484 483
485 virtual void Observe(int /* x */) OVERRIDE { 484 virtual void Observe(int /* x */) OVERRIDE {
486 list_->Clear(); 485 list_->Clear();
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
540 ObserverList<Foo>* observer_list = new ObserverList<Foo>; 539 ObserverList<Foo>* observer_list = new ObserverList<Foo>;
541 ListDestructor a(observer_list); 540 ListDestructor a(observer_list);
542 observer_list->AddObserver(&a); 541 observer_list->AddObserver(&a);
543 542
544 FOR_EACH_OBSERVER(Foo, *observer_list, Observe(0)); 543 FOR_EACH_OBSERVER(Foo, *observer_list, Observe(0));
545 // If this test fails, there'll be Valgrind errors when this function goes out 544 // If this test fails, there'll be Valgrind errors when this function goes out
546 // of scope. 545 // of scope.
547 } 546 }
548 547
549 } // namespace 548 } // namespace
549 } // namespace base
OLDNEW
« no previous file with comments | « base/metrics/field_trial_unittest.cc ('k') | base/prefs/json_pref_store_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698