Home | History | Annotate | Download | only in memory
      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
      3 // found in the LICENSE file.
      4 
      5 #include "base/memory/weak_ptr.h"
      6 
      7 #include <memory>
      8 #include <string>
      9 
     10 #include "base/bind.h"
     11 #include "base/debug/leak_annotations.h"
     12 #include "base/location.h"
     13 #include "base/single_thread_task_runner.h"
     14 #include "base/synchronization/waitable_event.h"
     15 #include "base/test/gtest_util.h"
     16 #include "base/threading/thread.h"
     17 #include "testing/gtest/include/gtest/gtest.h"
     18 
     19 namespace base {
     20 namespace {
     21 
     22 WeakPtr<int> PassThru(WeakPtr<int> ptr) {
     23   return ptr;
     24 }
     25 
     26 template <class T>
     27 class OffThreadObjectCreator {
     28  public:
     29   static T* NewObject() {
     30     T* result;
     31     {
     32       Thread creator_thread("creator_thread");
     33       creator_thread.Start();
     34       creator_thread.task_runner()->PostTask(
     35           FROM_HERE, base::Bind(OffThreadObjectCreator::CreateObject, &result));
     36     }
     37     DCHECK(result);  // We synchronized on thread destruction above.
     38     return result;
     39   }
     40  private:
     41   static void CreateObject(T** result) {
     42     *result = new T;
     43   }
     44 };
     45 
     46 struct Base {
     47   std::string member;
     48 };
     49 struct Derived : public Base {};
     50 
     51 struct TargetBase {};
     52 struct Target : public TargetBase, public SupportsWeakPtr<Target> {
     53   virtual ~Target() {}
     54 };
     55 struct DerivedTarget : public Target {};
     56 struct Arrow {
     57   WeakPtr<Target> target;
     58 };
     59 struct TargetWithFactory : public Target {
     60   TargetWithFactory() : factory(this) {}
     61   WeakPtrFactory<Target> factory;
     62 };
     63 
     64 // Helper class to create and destroy weak pointer copies
     65 // and delete objects on a background thread.
     66 class BackgroundThread : public Thread {
     67  public:
     68   BackgroundThread() : Thread("owner_thread") {}
     69 
     70   ~BackgroundThread() override { Stop(); }
     71 
     72   void CreateArrowFromTarget(Arrow** arrow, Target* target) {
     73     WaitableEvent completion(WaitableEvent::ResetPolicy::MANUAL,
     74                              WaitableEvent::InitialState::NOT_SIGNALED);
     75     task_runner()->PostTask(
     76         FROM_HERE, base::Bind(&BackgroundThread::DoCreateArrowFromTarget, arrow,
     77                               target, &completion));
     78     completion.Wait();
     79   }
     80 
     81   void CreateArrowFromArrow(Arrow** arrow, const Arrow* other) {
     82     WaitableEvent completion(WaitableEvent::ResetPolicy::MANUAL,
     83                              WaitableEvent::InitialState::NOT_SIGNALED);
     84     task_runner()->PostTask(
     85         FROM_HERE, base::Bind(&BackgroundThread::DoCreateArrowFromArrow, arrow,
     86                               other, &completion));
     87     completion.Wait();
     88   }
     89 
     90   void DeleteTarget(Target* object) {
     91     WaitableEvent completion(WaitableEvent::ResetPolicy::MANUAL,
     92                              WaitableEvent::InitialState::NOT_SIGNALED);
     93     task_runner()->PostTask(
     94         FROM_HERE,
     95         base::Bind(&BackgroundThread::DoDeleteTarget, object, &completion));
     96     completion.Wait();
     97   }
     98 
     99   void CopyAndAssignArrow(Arrow* object) {
    100     WaitableEvent completion(WaitableEvent::ResetPolicy::MANUAL,
    101                              WaitableEvent::InitialState::NOT_SIGNALED);
    102     task_runner()->PostTask(
    103         FROM_HERE, base::Bind(&BackgroundThread::DoCopyAndAssignArrow, object,
    104                               &completion));
    105     completion.Wait();
    106   }
    107 
    108   void CopyAndAssignArrowBase(Arrow* object) {
    109     WaitableEvent completion(WaitableEvent::ResetPolicy::MANUAL,
    110                              WaitableEvent::InitialState::NOT_SIGNALED);
    111     task_runner()->PostTask(
    112         FROM_HERE, base::Bind(&BackgroundThread::DoCopyAndAssignArrowBase,
    113                               object, &completion));
    114     completion.Wait();
    115   }
    116 
    117   void DeleteArrow(Arrow* object) {
    118     WaitableEvent completion(WaitableEvent::ResetPolicy::MANUAL,
    119                              WaitableEvent::InitialState::NOT_SIGNALED);
    120     task_runner()->PostTask(
    121         FROM_HERE,
    122         base::Bind(&BackgroundThread::DoDeleteArrow, object, &completion));
    123     completion.Wait();
    124   }
    125 
    126   Target* DeRef(const Arrow* arrow) {
    127     WaitableEvent completion(WaitableEvent::ResetPolicy::MANUAL,
    128                              WaitableEvent::InitialState::NOT_SIGNALED);
    129     Target* result = nullptr;
    130     task_runner()->PostTask(FROM_HERE, base::Bind(&BackgroundThread::DoDeRef,
    131                                                   arrow, &result, &completion));
    132     completion.Wait();
    133     return result;
    134   }
    135 
    136  protected:
    137   static void DoCreateArrowFromArrow(Arrow** arrow,
    138                                      const Arrow* other,
    139                                      WaitableEvent* completion) {
    140     *arrow = new Arrow;
    141     **arrow = *other;
    142     completion->Signal();
    143   }
    144 
    145   static void DoCreateArrowFromTarget(Arrow** arrow,
    146                                       Target* target,
    147                                       WaitableEvent* completion) {
    148     *arrow = new Arrow;
    149     (*arrow)->target = target->AsWeakPtr();
    150     completion->Signal();
    151   }
    152 
    153   static void DoDeRef(const Arrow* arrow,
    154                       Target** result,
    155                       WaitableEvent* completion) {
    156     *result = arrow->target.get();
    157     completion->Signal();
    158   }
    159 
    160   static void DoDeleteTarget(Target* object, WaitableEvent* completion) {
    161     delete object;
    162     completion->Signal();
    163   }
    164 
    165   static void DoCopyAndAssignArrow(Arrow* object, WaitableEvent* completion) {
    166     // Copy constructor.
    167     Arrow a = *object;
    168     // Assignment operator.
    169     *object = a;
    170     completion->Signal();
    171   }
    172 
    173   static void DoCopyAndAssignArrowBase(
    174       Arrow* object,
    175       WaitableEvent* completion) {
    176     // Copy constructor.
    177     WeakPtr<TargetBase> b = object->target;
    178     // Assignment operator.
    179     WeakPtr<TargetBase> c;
    180     c = object->target;
    181     completion->Signal();
    182   }
    183 
    184   static void DoDeleteArrow(Arrow* object, WaitableEvent* completion) {
    185     delete object;
    186     completion->Signal();
    187   }
    188 };
    189 
    190 }  // namespace
    191 
    192 TEST(WeakPtrFactoryTest, Basic) {
    193   int data;
    194   WeakPtrFactory<int> factory(&data);
    195   WeakPtr<int> ptr = factory.GetWeakPtr();
    196   EXPECT_EQ(&data, ptr.get());
    197 }
    198 
    199 TEST(WeakPtrFactoryTest, Comparison) {
    200   int data;
    201   WeakPtrFactory<int> factory(&data);
    202   WeakPtr<int> ptr = factory.GetWeakPtr();
    203   WeakPtr<int> ptr2 = ptr;
    204   EXPECT_EQ(ptr.get(), ptr2.get());
    205 }
    206 
    207 TEST(WeakPtrFactoryTest, Move) {
    208   int data;
    209   WeakPtrFactory<int> factory(&data);
    210   WeakPtr<int> ptr = factory.GetWeakPtr();
    211   WeakPtr<int> ptr2 = factory.GetWeakPtr();
    212   WeakPtr<int> ptr3 = std::move(ptr2);
    213   EXPECT_NE(ptr.get(), ptr2.get());
    214   EXPECT_EQ(ptr.get(), ptr3.get());
    215 }
    216 
    217 TEST(WeakPtrFactoryTest, OutOfScope) {
    218   WeakPtr<int> ptr;
    219   EXPECT_EQ(nullptr, ptr.get());
    220   {
    221     int data;
    222     WeakPtrFactory<int> factory(&data);
    223     ptr = factory.GetWeakPtr();
    224   }
    225   EXPECT_EQ(nullptr, ptr.get());
    226 }
    227 
    228 TEST(WeakPtrFactoryTest, Multiple) {
    229   WeakPtr<int> a, b;
    230   {
    231     int data;
    232     WeakPtrFactory<int> factory(&data);
    233     a = factory.GetWeakPtr();
    234     b = factory.GetWeakPtr();
    235     EXPECT_EQ(&data, a.get());
    236     EXPECT_EQ(&data, b.get());
    237   }
    238   EXPECT_EQ(nullptr, a.get());
    239   EXPECT_EQ(nullptr, b.get());
    240 }
    241 
    242 TEST(WeakPtrFactoryTest, MultipleStaged) {
    243   WeakPtr<int> a;
    244   {
    245     int data;
    246     WeakPtrFactory<int> factory(&data);
    247     a = factory.GetWeakPtr();
    248     {
    249       WeakPtr<int> b = factory.GetWeakPtr();
    250     }
    251     EXPECT_NE(nullptr, a.get());
    252   }
    253   EXPECT_EQ(nullptr, a.get());
    254 }
    255 
    256 TEST(WeakPtrFactoryTest, Dereference) {
    257   Base data;
    258   data.member = "123456";
    259   WeakPtrFactory<Base> factory(&data);
    260   WeakPtr<Base> ptr = factory.GetWeakPtr();
    261   EXPECT_EQ(&data, ptr.get());
    262   EXPECT_EQ(data.member, (*ptr).member);
    263   EXPECT_EQ(data.member, ptr->member);
    264 }
    265 
    266 TEST(WeakPtrFactoryTest, UpCast) {
    267   Derived data;
    268   WeakPtrFactory<Derived> factory(&data);
    269   WeakPtr<Base> ptr = factory.GetWeakPtr();
    270   ptr = factory.GetWeakPtr();
    271   EXPECT_EQ(ptr.get(), &data);
    272 }
    273 
    274 TEST(WeakPtrTest, ConstructFromNullptr) {
    275   WeakPtr<int> ptr = PassThru(nullptr);
    276   EXPECT_EQ(nullptr, ptr.get());
    277 }
    278 
    279 TEST(WeakPtrTest, SupportsWeakPtr) {
    280   Target target;
    281   WeakPtr<Target> ptr = target.AsWeakPtr();
    282   EXPECT_EQ(&target, ptr.get());
    283 }
    284 
    285 TEST(WeakPtrTest, DerivedTarget) {
    286   DerivedTarget target;
    287   WeakPtr<DerivedTarget> ptr = AsWeakPtr(&target);
    288   EXPECT_EQ(&target, ptr.get());
    289 }
    290 
    291 TEST(WeakPtrFactoryTest, BooleanTesting) {
    292   int data;
    293   WeakPtrFactory<int> factory(&data);
    294 
    295   WeakPtr<int> ptr_to_an_instance = factory.GetWeakPtr();
    296   EXPECT_TRUE(ptr_to_an_instance);
    297   EXPECT_FALSE(!ptr_to_an_instance);
    298 
    299   if (ptr_to_an_instance) {
    300   } else {
    301     ADD_FAILURE() << "Pointer to an instance should result in true.";
    302   }
    303 
    304   if (!ptr_to_an_instance) {  // check for operator!().
    305     ADD_FAILURE() << "Pointer to an instance should result in !x being false.";
    306   }
    307 
    308   WeakPtr<int> null_ptr;
    309   EXPECT_FALSE(null_ptr);
    310   EXPECT_TRUE(!null_ptr);
    311 
    312   if (null_ptr) {
    313     ADD_FAILURE() << "Null pointer should result in false.";
    314   }
    315 
    316   if (!null_ptr) {  // check for operator!().
    317   } else {
    318     ADD_FAILURE() << "Null pointer should result in !x being true.";
    319   }
    320 }
    321 
    322 TEST(WeakPtrFactoryTest, ComparisonToNull) {
    323   int data;
    324   WeakPtrFactory<int> factory(&data);
    325 
    326   WeakPtr<int> ptr_to_an_instance = factory.GetWeakPtr();
    327   EXPECT_NE(nullptr, ptr_to_an_instance);
    328   EXPECT_NE(ptr_to_an_instance, nullptr);
    329 
    330   WeakPtr<int> null_ptr;
    331   EXPECT_EQ(null_ptr, nullptr);
    332   EXPECT_EQ(nullptr, null_ptr);
    333 }
    334 
    335 TEST(WeakPtrTest, InvalidateWeakPtrs) {
    336   int data;
    337   WeakPtrFactory<int> factory(&data);
    338   WeakPtr<int> ptr = factory.GetWeakPtr();
    339   EXPECT_EQ(&data, ptr.get());
    340   EXPECT_TRUE(factory.HasWeakPtrs());
    341   factory.InvalidateWeakPtrs();
    342   EXPECT_EQ(nullptr, ptr.get());
    343   EXPECT_FALSE(factory.HasWeakPtrs());
    344 
    345   // Test that the factory can create new weak pointers after a
    346   // InvalidateWeakPtrs call, and they remain valid until the next
    347   // InvalidateWeakPtrs call.
    348   WeakPtr<int> ptr2 = factory.GetWeakPtr();
    349   EXPECT_EQ(&data, ptr2.get());
    350   EXPECT_TRUE(factory.HasWeakPtrs());
    351   factory.InvalidateWeakPtrs();
    352   EXPECT_EQ(nullptr, ptr2.get());
    353   EXPECT_FALSE(factory.HasWeakPtrs());
    354 }
    355 
    356 TEST(WeakPtrTest, HasWeakPtrs) {
    357   int data;
    358   WeakPtrFactory<int> factory(&data);
    359   {
    360     WeakPtr<int> ptr = factory.GetWeakPtr();
    361     EXPECT_TRUE(factory.HasWeakPtrs());
    362   }
    363   EXPECT_FALSE(factory.HasWeakPtrs());
    364 }
    365 
    366 TEST(WeakPtrTest, ObjectAndWeakPtrOnDifferentThreads) {
    367   // Test that it is OK to create an object that supports WeakPtr on one thread,
    368   // but use it on another.  This tests that we do not trip runtime checks that
    369   // ensure that a WeakPtr is not used by multiple threads.
    370   std::unique_ptr<Target> target(OffThreadObjectCreator<Target>::NewObject());
    371   WeakPtr<Target> weak_ptr = target->AsWeakPtr();
    372   EXPECT_EQ(target.get(), weak_ptr.get());
    373 }
    374 
    375 TEST(WeakPtrTest, WeakPtrInitiateAndUseOnDifferentThreads) {
    376   // Test that it is OK to create an object that has a WeakPtr member on one
    377   // thread, but use it on another.  This tests that we do not trip runtime
    378   // checks that ensure that a WeakPtr is not used by multiple threads.
    379   std::unique_ptr<Arrow> arrow(OffThreadObjectCreator<Arrow>::NewObject());
    380   Target target;
    381   arrow->target = target.AsWeakPtr();
    382   EXPECT_EQ(&target, arrow->target.get());
    383 }
    384 
    385 TEST(WeakPtrTest, MoveOwnershipImplicitly) {
    386   // Move object ownership to another thread by releasing all weak pointers
    387   // on the original thread first, and then establish WeakPtr on a different
    388   // thread.
    389   BackgroundThread background;
    390   background.Start();
    391 
    392   Target* target = new Target();
    393   {
    394     WeakPtr<Target> weak_ptr = target->AsWeakPtr();
    395     // Main thread deletes the WeakPtr, then the thread ownership of the
    396     // object can be implicitly moved.
    397   }
    398   Arrow* arrow;
    399 
    400   // Background thread creates WeakPtr(and implicitly owns the object).
    401   background.CreateArrowFromTarget(&arrow, target);
    402   EXPECT_EQ(background.DeRef(arrow), target);
    403 
    404   {
    405     // Main thread creates another WeakPtr, but this does not trigger implicitly
    406     // thread ownership move.
    407     Arrow arrow;
    408     arrow.target = target->AsWeakPtr();
    409 
    410     // The new WeakPtr is owned by background thread.
    411     EXPECT_EQ(target, background.DeRef(&arrow));
    412   }
    413 
    414   // Target can only be deleted on background thread.
    415   background.DeleteTarget(target);
    416   background.DeleteArrow(arrow);
    417 }
    418 
    419 TEST(WeakPtrTest, MoveOwnershipOfUnreferencedObject) {
    420   BackgroundThread background;
    421   background.Start();
    422 
    423   Arrow* arrow;
    424   {
    425     Target target;
    426     // Background thread creates WeakPtr.
    427     background.CreateArrowFromTarget(&arrow, &target);
    428 
    429     // Bind to background thread.
    430     EXPECT_EQ(&target, background.DeRef(arrow));
    431 
    432     // Release the only WeakPtr.
    433     arrow->target.reset();
    434 
    435     // Now we should be able to create a new reference from this thread.
    436     arrow->target = target.AsWeakPtr();
    437 
    438     // Re-bind to main thread.
    439     EXPECT_EQ(&target, arrow->target.get());
    440 
    441     // And the main thread can now delete the target.
    442   }
    443 
    444   delete arrow;
    445 }
    446 
    447 TEST(WeakPtrTest, MoveOwnershipAfterInvalidate) {
    448   BackgroundThread background;
    449   background.Start();
    450 
    451   Arrow arrow;
    452   std::unique_ptr<TargetWithFactory> target(new TargetWithFactory);
    453 
    454   // Bind to main thread.
    455   arrow.target = target->factory.GetWeakPtr();
    456   EXPECT_EQ(target.get(), arrow.target.get());
    457 
    458   target->factory.InvalidateWeakPtrs();
    459   EXPECT_EQ(nullptr, arrow.target.get());
    460 
    461   arrow.target = target->factory.GetWeakPtr();
    462   // Re-bind to background thread.
    463   EXPECT_EQ(target.get(), background.DeRef(&arrow));
    464 
    465   // And the background thread can now delete the target.
    466   background.DeleteTarget(target.release());
    467 }
    468 
    469 TEST(WeakPtrTest, MainThreadRefOutlivesBackgroundThreadRef) {
    470   // Originating thread has a WeakPtr that outlives others.
    471   // - Main thread creates a WeakPtr
    472   // - Background thread creates a WeakPtr copy from the one in main thread
    473   // - Destruct the WeakPtr on background thread
    474   // - Destruct the WeakPtr on main thread
    475   BackgroundThread background;
    476   background.Start();
    477 
    478   Target target;
    479   Arrow arrow;
    480   arrow.target = target.AsWeakPtr();
    481 
    482   Arrow* arrow_copy;
    483   background.CreateArrowFromArrow(&arrow_copy, &arrow);
    484   EXPECT_EQ(arrow_copy->target.get(), &target);
    485   background.DeleteArrow(arrow_copy);
    486 }
    487 
    488 TEST(WeakPtrTest, BackgroundThreadRefOutlivesMainThreadRef) {
    489   // Originating thread drops all references before another thread.
    490   // - Main thread creates a WeakPtr and passes copy to background thread
    491   // - Destruct the pointer on main thread
    492   // - Destruct the pointer on background thread
    493   BackgroundThread background;
    494   background.Start();
    495 
    496   Target target;
    497   Arrow* arrow_copy;
    498   {
    499     Arrow arrow;
    500     arrow.target = target.AsWeakPtr();
    501     background.CreateArrowFromArrow(&arrow_copy, &arrow);
    502   }
    503   EXPECT_EQ(arrow_copy->target.get(), &target);
    504   background.DeleteArrow(arrow_copy);
    505 }
    506 
    507 TEST(WeakPtrTest, OwnerThreadDeletesObject) {
    508   // Originating thread invalidates WeakPtrs while its held by other thread.
    509   // - Main thread creates WeakPtr and passes Copy to background thread
    510   // - Object gets destroyed on main thread
    511   //   (invalidates WeakPtr on background thread)
    512   // - WeakPtr gets destroyed on Thread B
    513   BackgroundThread background;
    514   background.Start();
    515   Arrow* arrow_copy;
    516   {
    517     Target target;
    518     Arrow arrow;
    519     arrow.target = target.AsWeakPtr();
    520     background.CreateArrowFromArrow(&arrow_copy, &arrow);
    521   }
    522   EXPECT_EQ(nullptr, arrow_copy->target.get());
    523   background.DeleteArrow(arrow_copy);
    524 }
    525 
    526 TEST(WeakPtrTest, NonOwnerThreadCanCopyAndAssignWeakPtr) {
    527   // Main thread creates a Target object.
    528   Target target;
    529   // Main thread creates an arrow referencing the Target.
    530   Arrow *arrow = new Arrow();
    531   arrow->target = target.AsWeakPtr();
    532 
    533   // Background can copy and assign arrow (as well as the WeakPtr inside).
    534   BackgroundThread background;
    535   background.Start();
    536   background.CopyAndAssignArrow(arrow);
    537   background.DeleteArrow(arrow);
    538 }
    539 
    540 TEST(WeakPtrTest, NonOwnerThreadCanCopyAndAssignWeakPtrBase) {
    541   // Main thread creates a Target object.
    542   Target target;
    543   // Main thread creates an arrow referencing the Target.
    544   Arrow *arrow = new Arrow();
    545   arrow->target = target.AsWeakPtr();
    546 
    547   // Background can copy and assign arrow's WeakPtr to a base class WeakPtr.
    548   BackgroundThread background;
    549   background.Start();
    550   background.CopyAndAssignArrowBase(arrow);
    551   background.DeleteArrow(arrow);
    552 }
    553 
    554 TEST(WeakPtrTest, NonOwnerThreadCanDeleteWeakPtr) {
    555   // Main thread creates a Target object.
    556   Target target;
    557   // Main thread creates an arrow referencing the Target.
    558   Arrow* arrow = new Arrow();
    559   arrow->target = target.AsWeakPtr();
    560 
    561   // Background can delete arrow (as well as the WeakPtr inside).
    562   BackgroundThread background;
    563   background.Start();
    564   background.DeleteArrow(arrow);
    565 }
    566 
    567 TEST(WeakPtrDeathTest, WeakPtrCopyDoesNotChangeThreadBinding) {
    568   // The default style "fast" does not support multi-threaded tests
    569   // (introduces deadlock on Linux).
    570   ::testing::FLAGS_gtest_death_test_style = "threadsafe";
    571 
    572   BackgroundThread background;
    573   background.Start();
    574 
    575   // Main thread creates a Target object.
    576   Target target;
    577   // Main thread creates an arrow referencing the Target.
    578   Arrow arrow;
    579   arrow.target = target.AsWeakPtr();
    580 
    581   // Background copies the WeakPtr.
    582   Arrow* arrow_copy;
    583   background.CreateArrowFromArrow(&arrow_copy, &arrow);
    584 
    585   // The copy is still bound to main thread so I can deref.
    586   EXPECT_EQ(arrow.target.get(), arrow_copy->target.get());
    587 
    588   // Although background thread created the copy, it can not deref the copied
    589   // WeakPtr.
    590   ASSERT_DCHECK_DEATH(background.DeRef(arrow_copy));
    591 
    592   background.DeleteArrow(arrow_copy);
    593 }
    594 
    595 TEST(WeakPtrDeathTest, NonOwnerThreadDereferencesWeakPtrAfterReference) {
    596   // The default style "fast" does not support multi-threaded tests
    597   // (introduces deadlock on Linux).
    598   ::testing::FLAGS_gtest_death_test_style = "threadsafe";
    599 
    600   // Main thread creates a Target object.
    601   Target target;
    602 
    603   // Main thread creates an arrow referencing the Target (so target's
    604   // thread ownership can not be implicitly moved).
    605   Arrow arrow;
    606   arrow.target = target.AsWeakPtr();
    607   arrow.target.get();
    608 
    609   // Background thread tries to deref target, which violates thread ownership.
    610   BackgroundThread background;
    611   background.Start();
    612   ASSERT_DCHECK_DEATH(background.DeRef(&arrow));
    613 }
    614 
    615 TEST(WeakPtrDeathTest, NonOwnerThreadDeletesWeakPtrAfterReference) {
    616   // The default style "fast" does not support multi-threaded tests
    617   // (introduces deadlock on Linux).
    618   ::testing::FLAGS_gtest_death_test_style = "threadsafe";
    619 
    620   std::unique_ptr<Target> target(new Target());
    621 
    622   // Main thread creates an arrow referencing the Target.
    623   Arrow arrow;
    624   arrow.target = target->AsWeakPtr();
    625 
    626   // Background thread tries to deref target, binding it to the thread.
    627   BackgroundThread background;
    628   background.Start();
    629   background.DeRef(&arrow);
    630 
    631   // Main thread deletes Target, violating thread binding.
    632   ASSERT_DCHECK_DEATH(target.reset());
    633 
    634   // |target.reset()| died so |target| still holds the object, so we
    635   // must pass it to the background thread to teardown.
    636   background.DeleteTarget(target.release());
    637 }
    638 
    639 TEST(WeakPtrDeathTest, NonOwnerThreadDeletesObjectAfterReference) {
    640   // The default style "fast" does not support multi-threaded tests
    641   // (introduces deadlock on Linux).
    642   ::testing::FLAGS_gtest_death_test_style = "threadsafe";
    643 
    644   std::unique_ptr<Target> target(new Target());
    645 
    646   // Main thread creates an arrow referencing the Target, and references it, so
    647   // that it becomes bound to the thread.
    648   Arrow arrow;
    649   arrow.target = target->AsWeakPtr();
    650   arrow.target.get();
    651 
    652   // Background thread tries to delete target, volating thread binding.
    653   BackgroundThread background;
    654   background.Start();
    655   ASSERT_DCHECK_DEATH(background.DeleteTarget(target.release()));
    656 }
    657 
    658 TEST(WeakPtrDeathTest, NonOwnerThreadReferencesObjectAfterDeletion) {
    659   // The default style "fast" does not support multi-threaded tests
    660   // (introduces deadlock on Linux).
    661   ::testing::FLAGS_gtest_death_test_style = "threadsafe";
    662 
    663   std::unique_ptr<Target> target(new Target());
    664 
    665   // Main thread creates an arrow referencing the Target.
    666   Arrow arrow;
    667   arrow.target = target->AsWeakPtr();
    668 
    669   // Background thread tries to delete target, binding the object to the thread.
    670   BackgroundThread background;
    671   background.Start();
    672   background.DeleteTarget(target.release());
    673 
    674   // Main thread attempts to dereference the target, violating thread binding.
    675   ASSERT_DCHECK_DEATH(arrow.target.get());
    676 }
    677 
    678 }  // namespace base
    679