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 
PassThru(WeakPtr<int> ptr)21 WeakPtr<int> PassThru(WeakPtr<int> ptr) {
22   return ptr;
23 }
24 
25 template <class T>
26 class OffThreadObjectCreator {
27  public:
NewObject()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:
CreateObject(T ** result)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> {
~Targetbase::__anonba1207970111::Target52   virtual ~Target() {}
53 };
54 struct DerivedTarget : public Target {};
55 struct Arrow {
56   WeakPtr<Target> target;
57 };
58 struct TargetWithFactory : public Target {
TargetWithFactorybase::__anonba1207970111::TargetWithFactory59   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:
BackgroundThread()67   BackgroundThread() : Thread("owner_thread") {}
68 
~BackgroundThread()69   ~BackgroundThread() override { Stop(); }
70 
CreateArrowFromTarget(Arrow ** arrow,Target * target)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 
CreateArrowFromArrow(Arrow ** arrow,const Arrow * other)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 
DeleteTarget(Target * object)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 
CopyAndAssignArrow(Arrow * object)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 
CopyAndAssignArrowBase(Arrow * object)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 
DeleteArrow(Arrow * object)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 
DeRef(const Arrow * arrow)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:
DoCreateArrowFromArrow(Arrow ** arrow,const Arrow * other,WaitableEvent * completion)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 
DoCreateArrowFromTarget(Arrow ** arrow,Target * target,WaitableEvent * completion)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 
DoDeRef(const Arrow * arrow,Target ** result,WaitableEvent * completion)152   static void DoDeRef(const Arrow* arrow,
153                       Target** result,
154                       WaitableEvent* completion) {
155     *result = arrow->target.get();
156     completion->Signal();
157   }
158 
DoDeleteTarget(Target * object,WaitableEvent * completion)159   static void DoDeleteTarget(Target* object, WaitableEvent* completion) {
160     delete object;
161     completion->Signal();
162   }
163 
DoCopyAndAssignArrow(Arrow * object,WaitableEvent * completion)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 
DoCopyAndAssignArrowBase(Arrow * object,WaitableEvent * completion)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 
DoDeleteArrow(Arrow * object,WaitableEvent * completion)183   static void DoDeleteArrow(Arrow* object, WaitableEvent* completion) {
184     delete object;
185     completion->Signal();
186   }
187 };
188 
189 }  // namespace
190 
TEST(WeakPtrFactoryTest,Basic)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 
TEST(WeakPtrFactoryTest,Comparison)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 
TEST(WeakPtrFactoryTest,Move)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 
TEST(WeakPtrFactoryTest,OutOfScope)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 
TEST(WeakPtrFactoryTest,Multiple)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 
TEST(WeakPtrFactoryTest,MultipleStaged)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 
TEST(WeakPtrFactoryTest,Dereference)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 
TEST(WeakPtrFactoryTest,UpCast)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 
TEST(WeakPtrTest,ConstructFromNullptr)273 TEST(WeakPtrTest, ConstructFromNullptr) {
274   WeakPtr<int> ptr = PassThru(nullptr);
275   EXPECT_EQ(nullptr, ptr.get());
276 }
277 
TEST(WeakPtrTest,SupportsWeakPtr)278 TEST(WeakPtrTest, SupportsWeakPtr) {
279   Target target;
280   WeakPtr<Target> ptr = target.AsWeakPtr();
281   EXPECT_EQ(&target, ptr.get());
282 }
283 
TEST(WeakPtrTest,DerivedTarget)284 TEST(WeakPtrTest, DerivedTarget) {
285   DerivedTarget target;
286   WeakPtr<DerivedTarget> ptr = AsWeakPtr(&target);
287   EXPECT_EQ(&target, ptr.get());
288 }
289 
TEST(WeakPtrFactoryTest,BooleanTesting)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 
TEST(WeakPtrFactoryTest,ComparisonToNull)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 
TEST(WeakPtrTest,InvalidateWeakPtrs)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 
TEST(WeakPtrTest,HasWeakPtrs)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 
TEST(WeakPtrTest,ObjectAndWeakPtrOnDifferentThreads)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 
TEST(WeakPtrTest,WeakPtrInitiateAndUseOnDifferentThreads)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 
TEST(WeakPtrTest,MoveOwnershipImplicitly)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 
TEST(WeakPtrTest,MoveOwnershipOfUnreferencedObject)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 
TEST(WeakPtrTest,MoveOwnershipAfterInvalidate)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 
TEST(WeakPtrTest,MainThreadRefOutlivesBackgroundThreadRef)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 
TEST(WeakPtrTest,BackgroundThreadRefOutlivesMainThreadRef)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 
TEST(WeakPtrTest,OwnerThreadDeletesObject)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 
TEST(WeakPtrTest,NonOwnerThreadCanCopyAndAssignWeakPtr)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 
TEST(WeakPtrTest,NonOwnerThreadCanCopyAndAssignWeakPtrBase)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 
TEST(WeakPtrTest,NonOwnerThreadCanDeleteWeakPtr)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 
TEST(WeakPtrDeathTest,WeakPtrCopyDoesNotChangeThreadBinding)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 
TEST(WeakPtrDeathTest,NonOwnerThreadDereferencesWeakPtrAfterReference)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 
TEST(WeakPtrDeathTest,NonOwnerThreadDeletesWeakPtrAfterReference)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 
TEST(WeakPtrDeathTest,NonOwnerThreadDeletesObjectAfterReference)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 
TEST(WeakPtrDeathTest,NonOwnerThreadReferencesObjectAfterDeletion)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