OLD | NEW |
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/memory/weak_ptr.h" | 5 #include "base/memory/weak_ptr.h" |
6 | 6 |
| 7 #include <memory> |
7 #include <string> | 8 #include <string> |
8 | 9 |
9 #include "base/bind.h" | 10 #include "base/bind.h" |
10 #include "base/debug/leak_annotations.h" | 11 #include "base/debug/leak_annotations.h" |
11 #include "base/location.h" | 12 #include "base/location.h" |
12 #include "base/memory/scoped_ptr.h" | |
13 #include "base/single_thread_task_runner.h" | 13 #include "base/single_thread_task_runner.h" |
14 #include "base/synchronization/waitable_event.h" | 14 #include "base/synchronization/waitable_event.h" |
15 #include "base/threading/thread.h" | 15 #include "base/threading/thread.h" |
16 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
17 | 17 |
18 namespace base { | 18 namespace base { |
19 namespace { | 19 namespace { |
20 | 20 |
21 template <class T> | 21 template <class T> |
22 class OffThreadObjectCreator { | 22 class OffThreadObjectCreator { |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
320 WeakPtr<int> ptr = factory.GetWeakPtr(); | 320 WeakPtr<int> ptr = factory.GetWeakPtr(); |
321 EXPECT_TRUE(factory.HasWeakPtrs()); | 321 EXPECT_TRUE(factory.HasWeakPtrs()); |
322 } | 322 } |
323 EXPECT_FALSE(factory.HasWeakPtrs()); | 323 EXPECT_FALSE(factory.HasWeakPtrs()); |
324 } | 324 } |
325 | 325 |
326 TEST(WeakPtrTest, ObjectAndWeakPtrOnDifferentThreads) { | 326 TEST(WeakPtrTest, ObjectAndWeakPtrOnDifferentThreads) { |
327 // Test that it is OK to create an object that supports WeakPtr on one thread, | 327 // Test that it is OK to create an object that supports WeakPtr on one thread, |
328 // but use it on another. This tests that we do not trip runtime checks that | 328 // but use it on another. This tests that we do not trip runtime checks that |
329 // ensure that a WeakPtr is not used by multiple threads. | 329 // ensure that a WeakPtr is not used by multiple threads. |
330 scoped_ptr<Target> target(OffThreadObjectCreator<Target>::NewObject()); | 330 std::unique_ptr<Target> target(OffThreadObjectCreator<Target>::NewObject()); |
331 WeakPtr<Target> weak_ptr = target->AsWeakPtr(); | 331 WeakPtr<Target> weak_ptr = target->AsWeakPtr(); |
332 EXPECT_EQ(target.get(), weak_ptr.get()); | 332 EXPECT_EQ(target.get(), weak_ptr.get()); |
333 } | 333 } |
334 | 334 |
335 TEST(WeakPtrTest, WeakPtrInitiateAndUseOnDifferentThreads) { | 335 TEST(WeakPtrTest, WeakPtrInitiateAndUseOnDifferentThreads) { |
336 // Test that it is OK to create an object that has a WeakPtr member on one | 336 // Test that it is OK to create an object that has a WeakPtr member on one |
337 // thread, but use it on another. This tests that we do not trip runtime | 337 // thread, but use it on another. This tests that we do not trip runtime |
338 // checks that ensure that a WeakPtr is not used by multiple threads. | 338 // checks that ensure that a WeakPtr is not used by multiple threads. |
339 scoped_ptr<Arrow> arrow(OffThreadObjectCreator<Arrow>::NewObject()); | 339 std::unique_ptr<Arrow> arrow(OffThreadObjectCreator<Arrow>::NewObject()); |
340 Target target; | 340 Target target; |
341 arrow->target = target.AsWeakPtr(); | 341 arrow->target = target.AsWeakPtr(); |
342 EXPECT_EQ(&target, arrow->target.get()); | 342 EXPECT_EQ(&target, arrow->target.get()); |
343 } | 343 } |
344 | 344 |
345 TEST(WeakPtrTest, MoveOwnershipImplicitly) { | 345 TEST(WeakPtrTest, MoveOwnershipImplicitly) { |
346 // Move object ownership to another thread by releasing all weak pointers | 346 // Move object ownership to another thread by releasing all weak pointers |
347 // on the original thread first, and then establish WeakPtr on a different | 347 // on the original thread first, and then establish WeakPtr on a different |
348 // thread. | 348 // thread. |
349 BackgroundThread background; | 349 BackgroundThread background; |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
402 } | 402 } |
403 | 403 |
404 delete arrow; | 404 delete arrow; |
405 } | 405 } |
406 | 406 |
407 TEST(WeakPtrTest, MoveOwnershipAfterInvalidate) { | 407 TEST(WeakPtrTest, MoveOwnershipAfterInvalidate) { |
408 BackgroundThread background; | 408 BackgroundThread background; |
409 background.Start(); | 409 background.Start(); |
410 | 410 |
411 Arrow arrow; | 411 Arrow arrow; |
412 scoped_ptr<TargetWithFactory> target(new TargetWithFactory); | 412 std::unique_ptr<TargetWithFactory> target(new TargetWithFactory); |
413 | 413 |
414 // Bind to main thread. | 414 // Bind to main thread. |
415 arrow.target = target->factory.GetWeakPtr(); | 415 arrow.target = target->factory.GetWeakPtr(); |
416 EXPECT_EQ(target.get(), arrow.target.get()); | 416 EXPECT_EQ(target.get(), arrow.target.get()); |
417 | 417 |
418 target->factory.InvalidateWeakPtrs(); | 418 target->factory.InvalidateWeakPtrs(); |
419 EXPECT_EQ(NULL, arrow.target.get()); | 419 EXPECT_EQ(NULL, arrow.target.get()); |
420 | 420 |
421 arrow.target = target->factory.GetWeakPtr(); | 421 arrow.target = target->factory.GetWeakPtr(); |
422 // Re-bind to background thread. | 422 // Re-bind to background thread. |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
572 BackgroundThread background; | 572 BackgroundThread background; |
573 background.Start(); | 573 background.Start(); |
574 ASSERT_DEATH(background.DeRef(&arrow), ""); | 574 ASSERT_DEATH(background.DeRef(&arrow), ""); |
575 } | 575 } |
576 | 576 |
577 TEST(WeakPtrDeathTest, NonOwnerThreadDeletesWeakPtrAfterReference) { | 577 TEST(WeakPtrDeathTest, NonOwnerThreadDeletesWeakPtrAfterReference) { |
578 // The default style "fast" does not support multi-threaded tests | 578 // The default style "fast" does not support multi-threaded tests |
579 // (introduces deadlock on Linux). | 579 // (introduces deadlock on Linux). |
580 ::testing::FLAGS_gtest_death_test_style = "threadsafe"; | 580 ::testing::FLAGS_gtest_death_test_style = "threadsafe"; |
581 | 581 |
582 scoped_ptr<Target> target(new Target()); | 582 std::unique_ptr<Target> target(new Target()); |
583 | 583 |
584 // Main thread creates an arrow referencing the Target. | 584 // Main thread creates an arrow referencing the Target. |
585 Arrow arrow; | 585 Arrow arrow; |
586 arrow.target = target->AsWeakPtr(); | 586 arrow.target = target->AsWeakPtr(); |
587 | 587 |
588 // Background thread tries to deref target, binding it to the thread. | 588 // Background thread tries to deref target, binding it to the thread. |
589 BackgroundThread background; | 589 BackgroundThread background; |
590 background.Start(); | 590 background.Start(); |
591 background.DeRef(&arrow); | 591 background.DeRef(&arrow); |
592 | 592 |
593 // Main thread deletes Target, violating thread binding. | 593 // Main thread deletes Target, violating thread binding. |
594 ASSERT_DEATH(target.reset(), ""); | 594 ASSERT_DEATH(target.reset(), ""); |
595 | 595 |
596 // |target.reset()| died so |target| still holds the object, so we | 596 // |target.reset()| died so |target| still holds the object, so we |
597 // must pass it to the background thread to teardown. | 597 // must pass it to the background thread to teardown. |
598 background.DeleteTarget(target.release()); | 598 background.DeleteTarget(target.release()); |
599 } | 599 } |
600 | 600 |
601 TEST(WeakPtrDeathTest, NonOwnerThreadDeletesObjectAfterReference) { | 601 TEST(WeakPtrDeathTest, NonOwnerThreadDeletesObjectAfterReference) { |
602 // The default style "fast" does not support multi-threaded tests | 602 // The default style "fast" does not support multi-threaded tests |
603 // (introduces deadlock on Linux). | 603 // (introduces deadlock on Linux). |
604 ::testing::FLAGS_gtest_death_test_style = "threadsafe"; | 604 ::testing::FLAGS_gtest_death_test_style = "threadsafe"; |
605 | 605 |
606 scoped_ptr<Target> target(new Target()); | 606 std::unique_ptr<Target> target(new Target()); |
607 | 607 |
608 // Main thread creates an arrow referencing the Target, and references it, so | 608 // Main thread creates an arrow referencing the Target, and references it, so |
609 // that it becomes bound to the thread. | 609 // that it becomes bound to the thread. |
610 Arrow arrow; | 610 Arrow arrow; |
611 arrow.target = target->AsWeakPtr(); | 611 arrow.target = target->AsWeakPtr(); |
612 arrow.target.get(); | 612 arrow.target.get(); |
613 | 613 |
614 // Background thread tries to delete target, volating thread binding. | 614 // Background thread tries to delete target, volating thread binding. |
615 BackgroundThread background; | 615 BackgroundThread background; |
616 background.Start(); | 616 background.Start(); |
617 ASSERT_DEATH(background.DeleteTarget(target.release()), ""); | 617 ASSERT_DEATH(background.DeleteTarget(target.release()), ""); |
618 } | 618 } |
619 | 619 |
620 TEST(WeakPtrDeathTest, NonOwnerThreadReferencesObjectAfterDeletion) { | 620 TEST(WeakPtrDeathTest, NonOwnerThreadReferencesObjectAfterDeletion) { |
621 // The default style "fast" does not support multi-threaded tests | 621 // The default style "fast" does not support multi-threaded tests |
622 // (introduces deadlock on Linux). | 622 // (introduces deadlock on Linux). |
623 ::testing::FLAGS_gtest_death_test_style = "threadsafe"; | 623 ::testing::FLAGS_gtest_death_test_style = "threadsafe"; |
624 | 624 |
625 scoped_ptr<Target> target(new Target()); | 625 std::unique_ptr<Target> target(new Target()); |
626 | 626 |
627 // Main thread creates an arrow referencing the Target. | 627 // Main thread creates an arrow referencing the Target. |
628 Arrow arrow; | 628 Arrow arrow; |
629 arrow.target = target->AsWeakPtr(); | 629 arrow.target = target->AsWeakPtr(); |
630 | 630 |
631 // Background thread tries to delete target, binding the object to the thread. | 631 // Background thread tries to delete target, binding the object to the thread. |
632 BackgroundThread background; | 632 BackgroundThread background; |
633 background.Start(); | 633 background.Start(); |
634 background.DeleteTarget(target.release()); | 634 background.DeleteTarget(target.release()); |
635 | 635 |
636 // Main thread attempts to dereference the target, violating thread binding. | 636 // Main thread attempts to dereference the target, violating thread binding. |
637 ASSERT_DEATH(arrow.target.get(), ""); | 637 ASSERT_DEATH(arrow.target.get(), ""); |
638 } | 638 } |
639 | 639 |
640 #endif | 640 #endif |
641 | 641 |
642 } // namespace base | 642 } // namespace base |
OLD | NEW |