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