• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2012 The Chromium Authors
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/debug/leak_annotations.h"
11 #include "base/functional/bind.h"
12 #include "base/location.h"
13 #include "base/synchronization/waitable_event.h"
14 #include "base/task/single_thread_task_runner.h"
15 #include "base/test/gtest_util.h"
16 #include "base/test/test_timeouts.h"
17 #include "base/threading/thread.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19 
20 namespace base {
21 
22 namespace subtle {
23 
24 class BindWeakPtrFactoryForTesting {
25  public:
26   template <typename T>
BindToCurrentSequence(WeakPtrFactory<T> & factory)27   static void BindToCurrentSequence(WeakPtrFactory<T>& factory) {
28     factory.BindToCurrentSequence(BindWeakPtrFactoryPassKey());
29   }
30 };
31 
32 }  // namespace subtle
33 
34 namespace {
35 
PassThru(WeakPtr<int> ptr)36 WeakPtr<int> PassThru(WeakPtr<int> ptr) {
37   return ptr;
38 }
39 
40 template <class T>
41 class OffThreadObjectCreator {
42  public:
NewObject()43   static T* NewObject() {
44     T* result;
45     {
46       Thread creator_thread("creator_thread");
47       creator_thread.Start();
48       creator_thread.task_runner()->PostTask(
49           FROM_HERE,
50           base::BindOnce(OffThreadObjectCreator::CreateObject, &result));
51     }
52     DCHECK(result);  // We synchronized on thread destruction above.
53     return result;
54   }
55  private:
CreateObject(T ** result)56   static void CreateObject(T** result) {
57     *result = new T;
58   }
59 };
60 
61 struct Base {
62   std::string member;
63 };
64 struct Derived : public Base {};
65 
66 struct TargetBase {};
67 
68 struct Target : public TargetBase {
69   virtual ~Target() = default;
AsWeakPtrbase::__anon45defd890111::Target70   WeakPtr<Target> AsWeakPtr() { return weak_ptr_factory_.GetWeakPtr(); }
71 
72  private:
73   WeakPtrFactory<Target> weak_ptr_factory_{this};
74 };
75 
76 struct DerivedTarget : public Target {};
77 
78 // A class inheriting from Target and defining a nested type called 'Base'.
79 // To guard against strange compilation errors.
80 struct DerivedTargetWithNestedBase : public Target {
81   using Base = void;
82 };
83 
84 // A struct with a virtual destructor.
85 struct VirtualDestructor {
86   virtual ~VirtualDestructor() = default;
87 };
88 
89 // A class inheriting from Target where Target is not the first base, and where
90 // the first base has a virtual method table. This creates a structure where the
91 // Target base is not positioned at the beginning of
92 // DerivedTargetMultipleInheritance.
93 struct DerivedTargetMultipleInheritance : public VirtualDestructor,
94                                           public Target {};
95 
96 struct Arrow {
97   WeakPtr<Target> target;
98 };
99 struct TargetWithFactory : public Target {
100   TargetWithFactory() = default;
101   WeakPtrFactory<Target> factory{this};
102 };
103 
104 // Helper class to create and destroy weak pointer copies
105 // and delete objects on a background thread.
106 class BackgroundThread : public Thread {
107  public:
BackgroundThread()108   BackgroundThread() : Thread("owner_thread") {}
109 
~BackgroundThread()110   ~BackgroundThread() override { Stop(); }
111 
CreateArrowFromTarget(Arrow ** arrow,Target * target)112   void CreateArrowFromTarget(Arrow** arrow, Target* target) {
113     WaitableEvent completion(WaitableEvent::ResetPolicy::MANUAL,
114                              WaitableEvent::InitialState::NOT_SIGNALED);
115     task_runner()->PostTask(
116         FROM_HERE, base::BindOnce(&BackgroundThread::DoCreateArrowFromTarget,
117                                   arrow, target, &completion));
118     completion.Wait();
119   }
120 
CreateArrowFromArrow(Arrow ** arrow,const Arrow * other)121   void CreateArrowFromArrow(Arrow** arrow, const Arrow* other) {
122     WaitableEvent completion(WaitableEvent::ResetPolicy::MANUAL,
123                              WaitableEvent::InitialState::NOT_SIGNALED);
124     task_runner()->PostTask(
125         FROM_HERE, base::BindOnce(&BackgroundThread::DoCreateArrowFromArrow,
126                                   arrow, other, &completion));
127     completion.Wait();
128   }
129 
DeleteTarget(Target * object)130   void DeleteTarget(Target* object) {
131     WaitableEvent completion(WaitableEvent::ResetPolicy::MANUAL,
132                              WaitableEvent::InitialState::NOT_SIGNALED);
133     task_runner()->PostTask(
134         FROM_HERE,
135         base::BindOnce(&BackgroundThread::DoDeleteTarget, object, &completion));
136     completion.Wait();
137   }
138 
CopyAndAssignArrow(Arrow * object)139   void CopyAndAssignArrow(Arrow* object) {
140     WaitableEvent completion(WaitableEvent::ResetPolicy::MANUAL,
141                              WaitableEvent::InitialState::NOT_SIGNALED);
142     task_runner()->PostTask(
143         FROM_HERE, base::BindOnce(&BackgroundThread::DoCopyAndAssignArrow,
144                                   object, &completion));
145     completion.Wait();
146   }
147 
CopyAndAssignArrowBase(Arrow * object)148   void CopyAndAssignArrowBase(Arrow* object) {
149     WaitableEvent completion(WaitableEvent::ResetPolicy::MANUAL,
150                              WaitableEvent::InitialState::NOT_SIGNALED);
151     task_runner()->PostTask(
152         FROM_HERE, base::BindOnce(&BackgroundThread::DoCopyAndAssignArrowBase,
153                                   object, &completion));
154     completion.Wait();
155   }
156 
DeleteArrow(Arrow * object)157   void DeleteArrow(Arrow* object) {
158     WaitableEvent completion(WaitableEvent::ResetPolicy::MANUAL,
159                              WaitableEvent::InitialState::NOT_SIGNALED);
160     task_runner()->PostTask(
161         FROM_HERE,
162         base::BindOnce(&BackgroundThread::DoDeleteArrow, object, &completion));
163     completion.Wait();
164   }
165 
DeRef(const Arrow * arrow)166   Target* DeRef(const Arrow* arrow) {
167     WaitableEvent completion(WaitableEvent::ResetPolicy::MANUAL,
168                              WaitableEvent::InitialState::NOT_SIGNALED);
169     Target* result = nullptr;
170     task_runner()->PostTask(
171         FROM_HERE, base::BindOnce(&BackgroundThread::DoDeRef, arrow, &result,
172                                   &completion));
173     completion.Wait();
174     return result;
175   }
176 
BindToCurrentSequence(TargetWithFactory * target_with_factory)177   void BindToCurrentSequence(TargetWithFactory* target_with_factory) {
178     WaitableEvent completion(WaitableEvent::ResetPolicy::MANUAL,
179                              WaitableEvent::InitialState::NOT_SIGNALED);
180     task_runner()->PostTask(
181         FROM_HERE, base::BindOnce(&BackgroundThread::DoBindToCurrentSequence,
182                                   target_with_factory, &completion));
183     completion.Wait();
184   }
185 
186  protected:
DoCreateArrowFromArrow(Arrow ** arrow,const Arrow * other,WaitableEvent * completion)187   static void DoCreateArrowFromArrow(Arrow** arrow,
188                                      const Arrow* other,
189                                      WaitableEvent* completion) {
190     *arrow = new Arrow;
191     **arrow = *other;
192     completion->Signal();
193   }
194 
DoCreateArrowFromTarget(Arrow ** arrow,Target * target,WaitableEvent * completion)195   static void DoCreateArrowFromTarget(Arrow** arrow,
196                                       Target* target,
197                                       WaitableEvent* completion) {
198     *arrow = new Arrow;
199     (*arrow)->target = target->AsWeakPtr();
200     completion->Signal();
201   }
202 
DoDeRef(const Arrow * arrow,Target ** result,WaitableEvent * completion)203   static void DoDeRef(const Arrow* arrow,
204                       Target** result,
205                       WaitableEvent* completion) {
206     *result = arrow->target.get();
207     completion->Signal();
208   }
209 
DoDeleteTarget(Target * object,WaitableEvent * completion)210   static void DoDeleteTarget(Target* object, WaitableEvent* completion) {
211     delete object;
212     completion->Signal();
213   }
214 
DoCopyAndAssignArrow(Arrow * object,WaitableEvent * completion)215   static void DoCopyAndAssignArrow(Arrow* object, WaitableEvent* completion) {
216     // Copy constructor.
217     Arrow a = *object;
218     // Assignment operator.
219     *object = a;
220     completion->Signal();
221   }
222 
DoCopyAndAssignArrowBase(Arrow * object,WaitableEvent * completion)223   static void DoCopyAndAssignArrowBase(
224       Arrow* object,
225       WaitableEvent* completion) {
226     // Copy constructor.
227     WeakPtr<TargetBase> b = object->target;
228     // Assignment operator.
229     WeakPtr<TargetBase> c;
230     c = object->target;
231     completion->Signal();
232   }
233 
DoDeleteArrow(Arrow * object,WaitableEvent * completion)234   static void DoDeleteArrow(Arrow* object, WaitableEvent* completion) {
235     delete object;
236     completion->Signal();
237   }
238 
DoBindToCurrentSequence(TargetWithFactory * target_with_factory,WaitableEvent * completion)239   static void DoBindToCurrentSequence(TargetWithFactory* target_with_factory,
240                                       WaitableEvent* completion) {
241     subtle::BindWeakPtrFactoryForTesting::BindToCurrentSequence(
242         target_with_factory->factory);
243     completion->Signal();
244   }
245 };
246 
247 }  // namespace
248 
TEST(WeakPtrFactoryTest,Basic)249 TEST(WeakPtrFactoryTest, Basic) {
250   int data;
251   WeakPtrFactory<int> factory(&data);
252   WeakPtr<int> ptr = factory.GetWeakPtr();
253   EXPECT_EQ(&data, ptr.get());
254 }
255 
TEST(WeakPtrFactoryTest,Comparison)256 TEST(WeakPtrFactoryTest, Comparison) {
257   int data;
258   WeakPtrFactory<int> factory(&data);
259   WeakPtr<int> ptr = factory.GetWeakPtr();
260   WeakPtr<int> ptr2 = ptr;
261   EXPECT_EQ(ptr.get(), ptr2.get());
262 }
263 
TEST(WeakPtrFactoryTest,Move)264 TEST(WeakPtrFactoryTest, Move) {
265   int data;
266   WeakPtrFactory<int> factory(&data);
267   WeakPtr<int> ptr = factory.GetWeakPtr();
268   WeakPtr<int> ptr2 = factory.GetWeakPtr();
269   WeakPtr<int> ptr3 = std::move(ptr2);
270   EXPECT_NE(ptr.get(), ptr2.get());
271   EXPECT_EQ(ptr.get(), ptr3.get());
272 }
273 
TEST(WeakPtrFactoryTest,OutOfScope)274 TEST(WeakPtrFactoryTest, OutOfScope) {
275   WeakPtr<int> ptr;
276   EXPECT_EQ(nullptr, ptr.get());
277   {
278     int data;
279     WeakPtrFactory<int> factory(&data);
280     ptr = factory.GetWeakPtr();
281   }
282   EXPECT_EQ(nullptr, ptr.get());
283 }
284 
TEST(WeakPtrFactoryTest,Multiple)285 TEST(WeakPtrFactoryTest, Multiple) {
286   WeakPtr<int> a, b;
287   {
288     int data;
289     WeakPtrFactory<int> factory(&data);
290     a = factory.GetWeakPtr();
291     b = factory.GetWeakPtr();
292     EXPECT_EQ(&data, a.get());
293     EXPECT_EQ(&data, b.get());
294   }
295   EXPECT_EQ(nullptr, a.get());
296   EXPECT_EQ(nullptr, b.get());
297 }
298 
TEST(WeakPtrFactoryTest,MultipleStaged)299 TEST(WeakPtrFactoryTest, MultipleStaged) {
300   WeakPtr<int> a;
301   {
302     int data;
303     WeakPtrFactory<int> factory(&data);
304     a = factory.GetWeakPtr();
305     {
306       WeakPtr<int> b = factory.GetWeakPtr();
307     }
308     EXPECT_NE(nullptr, a.get());
309   }
310   EXPECT_EQ(nullptr, a.get());
311 }
312 
TEST(WeakPtrFactoryTest,Dereference)313 TEST(WeakPtrFactoryTest, Dereference) {
314   Base data;
315   data.member = "123456";
316   WeakPtrFactory<Base> factory(&data);
317   WeakPtr<Base> ptr = factory.GetWeakPtr();
318   EXPECT_EQ(&data, ptr.get());
319   EXPECT_EQ(data.member, (*ptr).member);
320   EXPECT_EQ(data.member, ptr->member);
321 }
322 
TEST(WeakPtrFactoryTest,UpCast)323 TEST(WeakPtrFactoryTest, UpCast) {
324   Derived data;
325   WeakPtrFactory<Derived> factory(&data);
326   WeakPtr<Base> ptr = factory.GetWeakPtr();
327   ptr = factory.GetWeakPtr();
328   EXPECT_EQ(ptr.get(), &data);
329 }
330 
TEST(WeakPtrTest,ConstructFromNullptr)331 TEST(WeakPtrTest, ConstructFromNullptr) {
332   WeakPtr<int> ptr = PassThru(nullptr);
333   EXPECT_EQ(nullptr, ptr.get());
334 }
335 
TEST(WeakPtrFactoryTest,BooleanTesting)336 TEST(WeakPtrFactoryTest, BooleanTesting) {
337   int data;
338   WeakPtrFactory<int> factory(&data);
339 
340   WeakPtr<int> ptr_to_an_instance = factory.GetWeakPtr();
341   EXPECT_TRUE(ptr_to_an_instance);
342   EXPECT_FALSE(!ptr_to_an_instance);
343 
344   if (ptr_to_an_instance) {
345   } else {
346     ADD_FAILURE() << "Pointer to an instance should result in true.";
347   }
348 
349   if (!ptr_to_an_instance) {  // check for operator!().
350     ADD_FAILURE() << "Pointer to an instance should result in !x being false.";
351   }
352 
353   WeakPtr<int> null_ptr;
354   EXPECT_FALSE(null_ptr);
355   EXPECT_TRUE(!null_ptr);
356 
357   if (null_ptr) {
358     ADD_FAILURE() << "Null pointer should result in false.";
359   }
360 
361   if (!null_ptr) {  // check for operator!().
362   } else {
363     ADD_FAILURE() << "Null pointer should result in !x being true.";
364   }
365 }
366 
TEST(WeakPtrFactoryTest,ComparisonToNull)367 TEST(WeakPtrFactoryTest, ComparisonToNull) {
368   int data;
369   WeakPtrFactory<int> factory(&data);
370 
371   WeakPtr<int> ptr_to_an_instance = factory.GetWeakPtr();
372   EXPECT_NE(nullptr, ptr_to_an_instance);
373   EXPECT_NE(ptr_to_an_instance, nullptr);
374 
375   WeakPtr<int> null_ptr;
376   EXPECT_EQ(null_ptr, nullptr);
377   EXPECT_EQ(nullptr, null_ptr);
378 }
379 
380 struct ReallyBaseClass {};
381 struct BaseClass : ReallyBaseClass {
382   virtual ~BaseClass() = default;
VirtualMethodbase::BaseClass383   void VirtualMethod() {}
384 };
385 struct OtherBaseClass {
386   virtual ~OtherBaseClass() = default;
VirtualMethodbase::OtherBaseClass387   virtual void VirtualMethod() {}
388 };
389 struct WithWeak final : BaseClass, OtherBaseClass {
390   WeakPtrFactory<WithWeak> factory{this};
391 };
392 
TEST(WeakPtrTest,ConversionOffsetsPointer)393 TEST(WeakPtrTest, ConversionOffsetsPointer) {
394   WithWeak with;
395   WeakPtr<WithWeak> ptr(with.factory.GetWeakPtr());
396   {
397     // Copy construction.
398     WeakPtr<OtherBaseClass> base_ptr(ptr);
399     EXPECT_EQ(static_cast<WithWeak*>(&*base_ptr), &with);
400   }
401   {
402     // Move construction.
403     WeakPtr<OtherBaseClass> base_ptr(std::move(ptr));
404     EXPECT_EQ(static_cast<WithWeak*>(&*base_ptr), &with);
405   }
406 
407   // WeakPtr doesn't have conversion operators for assignment.
408 }
409 
TEST(WeakPtrTest,InvalidateWeakPtrs)410 TEST(WeakPtrTest, InvalidateWeakPtrs) {
411   int data;
412   WeakPtrFactory<int> factory(&data);
413   WeakPtr<int> ptr = factory.GetWeakPtr();
414   EXPECT_EQ(&data, ptr.get());
415   EXPECT_TRUE(factory.HasWeakPtrs());
416   factory.InvalidateWeakPtrs();
417   EXPECT_EQ(nullptr, ptr.get());
418   EXPECT_FALSE(factory.HasWeakPtrs());
419 
420   // Test that the factory can create new weak pointers after a
421   // InvalidateWeakPtrs call, and they remain valid until the next
422   // InvalidateWeakPtrs call.
423   WeakPtr<int> ptr2 = factory.GetWeakPtr();
424   EXPECT_EQ(&data, ptr2.get());
425   EXPECT_TRUE(factory.HasWeakPtrs());
426   factory.InvalidateWeakPtrs();
427   EXPECT_EQ(nullptr, ptr2.get());
428   EXPECT_FALSE(factory.HasWeakPtrs());
429 }
430 
431 // Tests that WasInvalidated() is true only for invalidated WeakPtrs (not
432 // nullptr) and doesn't DCHECK (e.g. because of a dereference attempt).
TEST(WeakPtrTest,WasInvalidatedByFactoryDestruction)433 TEST(WeakPtrTest, WasInvalidatedByFactoryDestruction) {
434   WeakPtr<int> ptr;
435   EXPECT_FALSE(ptr.WasInvalidated());
436 
437   // Test |data| destroyed. That is, the typical pattern when |data| (and its
438   // associated factory) go out of scope.
439   {
440     int data = 0;
441     WeakPtrFactory<int> factory(&data);
442     ptr = factory.GetWeakPtr();
443 
444     // Verify that a live WeakPtr is not reported as Invalidated.
445     EXPECT_FALSE(ptr.WasInvalidated());
446   }
447 
448   // Checking validity shouldn't read beyond the stack frame.
449   EXPECT_TRUE(ptr.WasInvalidated());
450   ptr = nullptr;
451   EXPECT_FALSE(ptr.WasInvalidated());
452 }
453 
454 // As above, but testing InvalidateWeakPtrs().
TEST(WeakPtrTest,WasInvalidatedByInvalidateWeakPtrs)455 TEST(WeakPtrTest, WasInvalidatedByInvalidateWeakPtrs) {
456   int data = 0;
457   WeakPtrFactory<int> factory(&data);
458   WeakPtr<int> ptr = factory.GetWeakPtr();
459   EXPECT_FALSE(ptr.WasInvalidated());
460   factory.InvalidateWeakPtrs();
461   EXPECT_TRUE(ptr.WasInvalidated());
462   ptr = nullptr;
463   EXPECT_FALSE(ptr.WasInvalidated());
464 }
465 
466 // A WeakPtr should not be reported as 'invalidated' if nullptr was assigned to
467 // it.
TEST(WeakPtrTest,WasInvalidatedWhilstNull)468 TEST(WeakPtrTest, WasInvalidatedWhilstNull) {
469   int data = 0;
470   WeakPtrFactory<int> factory(&data);
471   WeakPtr<int> ptr = factory.GetWeakPtr();
472   EXPECT_FALSE(ptr.WasInvalidated());
473   ptr = nullptr;
474   EXPECT_FALSE(ptr.WasInvalidated());
475   factory.InvalidateWeakPtrs();
476   EXPECT_FALSE(ptr.WasInvalidated());
477 }
478 
TEST(WeakPtrTest,MaybeValidOnSameSequence)479 TEST(WeakPtrTest, MaybeValidOnSameSequence) {
480   int data;
481   WeakPtrFactory<int> factory(&data);
482   WeakPtr<int> ptr = factory.GetWeakPtr();
483   EXPECT_TRUE(ptr.MaybeValid());
484   factory.InvalidateWeakPtrs();
485   // Since InvalidateWeakPtrs() ran on this sequence, MaybeValid() should be
486   // false.
487   EXPECT_FALSE(ptr.MaybeValid());
488 }
489 
TEST(WeakPtrTest,MaybeValidOnOtherSequence)490 TEST(WeakPtrTest, MaybeValidOnOtherSequence) {
491   int data;
492   WeakPtrFactory<int> factory(&data);
493   WeakPtr<int> ptr = factory.GetWeakPtr();
494   EXPECT_TRUE(ptr.MaybeValid());
495 
496   base::Thread other_thread("other_thread");
497   other_thread.StartAndWaitForTesting();
498   other_thread.task_runner()->PostTask(
499       FROM_HERE,
500       base::BindOnce(
501           [](WeakPtr<int> ptr) {
502             // Check that MaybeValid() _eventually_ returns false.
503             const TimeDelta timeout = TestTimeouts::tiny_timeout();
504             const TimeTicks begin = TimeTicks::Now();
505             while (ptr.MaybeValid() && (TimeTicks::Now() - begin) < timeout)
506               PlatformThread::YieldCurrentThread();
507             EXPECT_FALSE(ptr.MaybeValid());
508           },
509           ptr));
510   factory.InvalidateWeakPtrs();
511   // |other_thread|'s destructor will join, ensuring we wait for the task to be
512   // run.
513 }
514 
TEST(WeakPtrTest,HasWeakPtrs)515 TEST(WeakPtrTest, HasWeakPtrs) {
516   int data;
517   WeakPtrFactory<int> factory(&data);
518   {
519     WeakPtr<int> ptr = factory.GetWeakPtr();
520     EXPECT_TRUE(factory.HasWeakPtrs());
521   }
522   EXPECT_FALSE(factory.HasWeakPtrs());
523 }
524 
TEST(WeakPtrTest,ObjectAndWeakPtrOnDifferentThreads)525 TEST(WeakPtrTest, ObjectAndWeakPtrOnDifferentThreads) {
526   // Test that it is OK to create an object that supports WeakPtr on one thread,
527   // but use it on another.  This tests that we do not trip runtime checks that
528   // ensure that a WeakPtr is not used by multiple threads.
529   std::unique_ptr<Target> target(OffThreadObjectCreator<Target>::NewObject());
530   WeakPtr<Target> weak_ptr = target->AsWeakPtr();
531   EXPECT_EQ(target.get(), weak_ptr.get());
532 }
533 
TEST(WeakPtrTest,WeakPtrInitiateAndUseOnDifferentThreads)534 TEST(WeakPtrTest, WeakPtrInitiateAndUseOnDifferentThreads) {
535   // Test that it is OK to create an object that has a WeakPtr member on one
536   // thread, but use it on another.  This tests that we do not trip runtime
537   // checks that ensure that a WeakPtr is not used by multiple threads.
538   std::unique_ptr<Arrow> arrow(OffThreadObjectCreator<Arrow>::NewObject());
539   Target target;
540   arrow->target = target.AsWeakPtr();
541   EXPECT_EQ(&target, arrow->target.get());
542 }
543 
TEST(WeakPtrTest,MoveOwnershipImplicitly)544 TEST(WeakPtrTest, MoveOwnershipImplicitly) {
545   // Move object ownership to another thread by releasing all weak pointers
546   // on the original thread first, and then establish WeakPtr on a different
547   // thread.
548   BackgroundThread background;
549   background.Start();
550 
551   Target* target = new Target();
552   {
553     WeakPtr<Target> weak_ptr = target->AsWeakPtr();
554     // Main thread deletes the WeakPtr, then the thread ownership of the
555     // object can be implicitly moved.
556   }
557   Arrow* arrow;
558 
559   // Background thread creates WeakPtr(and implicitly owns the object).
560   background.CreateArrowFromTarget(&arrow, target);
561   EXPECT_EQ(background.DeRef(arrow), target);
562 
563   {
564     // Main thread creates another WeakPtr, but this does not trigger implicitly
565     // thread ownership move.
566     Arrow scoped_arrow;
567     scoped_arrow.target = target->AsWeakPtr();
568 
569     // The new WeakPtr is owned by background thread.
570     EXPECT_EQ(target, background.DeRef(&scoped_arrow));
571   }
572 
573   // Target can only be deleted on background thread.
574   background.DeleteTarget(target);
575   background.DeleteArrow(arrow);
576 }
577 
TEST(WeakPtrTest,MoveOwnershipOfUnreferencedObject)578 TEST(WeakPtrTest, MoveOwnershipOfUnreferencedObject) {
579   BackgroundThread background;
580   background.Start();
581 
582   Arrow* arrow;
583   {
584     Target target;
585     // Background thread creates WeakPtr.
586     background.CreateArrowFromTarget(&arrow, &target);
587 
588     // Bind to background thread.
589     EXPECT_EQ(&target, background.DeRef(arrow));
590 
591     // Release the only WeakPtr.
592     arrow->target.reset();
593 
594     // Now we should be able to create a new reference from this thread.
595     arrow->target = target.AsWeakPtr();
596 
597     // Re-bind to main thread.
598     EXPECT_EQ(&target, arrow->target.get());
599 
600     // And the main thread can now delete the target.
601   }
602 
603   delete arrow;
604 }
605 
TEST(WeakPtrTest,MoveOwnershipAfterInvalidate)606 TEST(WeakPtrTest, MoveOwnershipAfterInvalidate) {
607   BackgroundThread background;
608   background.Start();
609 
610   Arrow arrow;
611   std::unique_ptr<TargetWithFactory> target(new TargetWithFactory);
612 
613   // Bind to main thread.
614   arrow.target = target->factory.GetWeakPtr();
615   EXPECT_EQ(target.get(), arrow.target.get());
616 
617   target->factory.InvalidateWeakPtrs();
618   EXPECT_EQ(nullptr, arrow.target.get());
619 
620   arrow.target = target->factory.GetWeakPtr();
621   // Re-bind to background thread.
622   EXPECT_EQ(target.get(), background.DeRef(&arrow));
623 
624   // And the background thread can now delete the target.
625   background.DeleteTarget(target.release());
626 }
627 
TEST(WeakPtrTest,MainThreadRefOutlivesBackgroundThreadRef)628 TEST(WeakPtrTest, MainThreadRefOutlivesBackgroundThreadRef) {
629   // Originating thread has a WeakPtr that outlives others.
630   // - Main thread creates a WeakPtr
631   // - Background thread creates a WeakPtr copy from the one in main thread
632   // - Destruct the WeakPtr on background thread
633   // - Destruct the WeakPtr on main thread
634   BackgroundThread background;
635   background.Start();
636 
637   Target target;
638   Arrow arrow;
639   arrow.target = target.AsWeakPtr();
640 
641   Arrow* arrow_copy;
642   background.CreateArrowFromArrow(&arrow_copy, &arrow);
643   EXPECT_EQ(arrow_copy->target.get(), &target);
644   background.DeleteArrow(arrow_copy);
645 }
646 
TEST(WeakPtrTest,BackgroundThreadRefOutlivesMainThreadRef)647 TEST(WeakPtrTest, BackgroundThreadRefOutlivesMainThreadRef) {
648   // Originating thread drops all references before another thread.
649   // - Main thread creates a WeakPtr and passes copy to background thread
650   // - Destruct the pointer on main thread
651   // - Destruct the pointer on background thread
652   BackgroundThread background;
653   background.Start();
654 
655   Target target;
656   Arrow* arrow_copy;
657   {
658     Arrow arrow;
659     arrow.target = target.AsWeakPtr();
660     background.CreateArrowFromArrow(&arrow_copy, &arrow);
661   }
662   EXPECT_EQ(arrow_copy->target.get(), &target);
663   background.DeleteArrow(arrow_copy);
664 }
665 
TEST(WeakPtrTest,OwnerThreadDeletesObject)666 TEST(WeakPtrTest, OwnerThreadDeletesObject) {
667   // Originating thread invalidates WeakPtrs while its held by other thread.
668   // - Main thread creates WeakPtr and passes Copy to background thread
669   // - Object gets destroyed on main thread
670   //   (invalidates WeakPtr on background thread)
671   // - WeakPtr gets destroyed on Thread B
672   BackgroundThread background;
673   background.Start();
674   Arrow* arrow_copy;
675   {
676     Target target;
677     Arrow arrow;
678     arrow.target = target.AsWeakPtr();
679     background.CreateArrowFromArrow(&arrow_copy, &arrow);
680   }
681   EXPECT_EQ(nullptr, arrow_copy->target.get());
682   background.DeleteArrow(arrow_copy);
683 }
684 
TEST(WeakPtrTest,NonOwnerThreadCanCopyAndAssignWeakPtr)685 TEST(WeakPtrTest, NonOwnerThreadCanCopyAndAssignWeakPtr) {
686   // Main thread creates a Target object.
687   Target target;
688   // Main thread creates an arrow referencing the Target.
689   Arrow *arrow = new Arrow();
690   arrow->target = target.AsWeakPtr();
691 
692   // Background can copy and assign arrow (as well as the WeakPtr inside).
693   BackgroundThread background;
694   background.Start();
695   background.CopyAndAssignArrow(arrow);
696   background.DeleteArrow(arrow);
697 }
698 
TEST(WeakPtrTest,NonOwnerThreadCanCopyAndAssignWeakPtrBase)699 TEST(WeakPtrTest, NonOwnerThreadCanCopyAndAssignWeakPtrBase) {
700   // Main thread creates a Target object.
701   Target target;
702   // Main thread creates an arrow referencing the Target.
703   Arrow *arrow = new Arrow();
704   arrow->target = target.AsWeakPtr();
705 
706   // Background can copy and assign arrow's WeakPtr to a base class WeakPtr.
707   BackgroundThread background;
708   background.Start();
709   background.CopyAndAssignArrowBase(arrow);
710   background.DeleteArrow(arrow);
711 }
712 
TEST(WeakPtrTest,NonOwnerThreadCanDeleteWeakPtr)713 TEST(WeakPtrTest, NonOwnerThreadCanDeleteWeakPtr) {
714   // Main thread creates a Target object.
715   Target target;
716   // Main thread creates an arrow referencing the Target.
717   Arrow* arrow = new Arrow();
718   arrow->target = target.AsWeakPtr();
719 
720   // Background can delete arrow (as well as the WeakPtr inside).
721   BackgroundThread background;
722   background.Start();
723   background.DeleteArrow(arrow);
724 }
725 
TEST(WeakPtrTest,ConstUpCast)726 TEST(WeakPtrTest, ConstUpCast) {
727   Target target;
728 
729   // WeakPtrs can upcast from non-const T to const T.
730   WeakPtr<const Target> const_weak_ptr = target.AsWeakPtr();
731 
732   // WeakPtrs don't enable conversion from const T to nonconst T.
733   static_assert(
734       !std::is_constructible_v<WeakPtr<Target>, WeakPtr<const Target>>);
735 }
736 
TEST(WeakPtrTest,ConstGetWeakPtr)737 TEST(WeakPtrTest, ConstGetWeakPtr) {
738   struct TestTarget {
739     const char* Method() const { return "const method"; }
740     const char* Method() { return "non-const method"; }
741 
742     WeakPtrFactory<TestTarget> weak_ptr_factory{this};
743   } non_const_test_target;
744 
745   const TestTarget& const_test_target = non_const_test_target;
746 
747   EXPECT_EQ(const_test_target.weak_ptr_factory.GetWeakPtr()->Method(),
748             "const method");
749   EXPECT_EQ(non_const_test_target.weak_ptr_factory.GetWeakPtr()->Method(),
750             "non-const method");
751   EXPECT_EQ(const_test_target.weak_ptr_factory.GetMutableWeakPtr()->Method(),
752             "non-const method");
753 }
754 
TEST(WeakPtrTest,GetMutableWeakPtr)755 TEST(WeakPtrTest, GetMutableWeakPtr) {
756   struct TestStruct {
757     int member = 0;
758     WeakPtrFactory<TestStruct> weak_ptr_factory{this};
759   };
760   TestStruct test_struct;
761   EXPECT_EQ(test_struct.member, 0);
762 
763   // GetMutableWeakPtr() grants non-const access to T.
764   const TestStruct& const_test_struct = test_struct;
765   WeakPtr<TestStruct> weak_ptr =
766       const_test_struct.weak_ptr_factory.GetMutableWeakPtr();
767   weak_ptr->member = 1;
768   EXPECT_EQ(test_struct.member, 1);
769 }
770 
TEST(WeakPtrDeathTest,BindToCurrentSequence)771 TEST(WeakPtrDeathTest, BindToCurrentSequence) {
772   BackgroundThread background;
773   background.Start();
774 
775   TargetWithFactory target_with_factory;
776   Arrow arrow{
777       .target = target_with_factory.factory.GetWeakPtr(),
778   };
779 
780   // WeakPtr can be accessed on main thread.
781   EXPECT_TRUE(arrow.target.get());
782 
783   background.BindToCurrentSequence(&target_with_factory);
784 
785   // Now WeakPtr can be accessed on background thread.
786   EXPECT_TRUE(background.DeRef(&arrow));
787 
788   // WeakPtr can no longer be accessed on main thread.
789   EXPECT_DCHECK_DEATH(arrow.target.get());
790 }
791 
TEST(WeakPtrDeathTest,WeakPtrCopyDoesNotChangeThreadBinding)792 TEST(WeakPtrDeathTest, WeakPtrCopyDoesNotChangeThreadBinding) {
793   // The default style "fast" does not support multi-threaded tests
794   // (introduces deadlock on Linux).
795   GTEST_FLAG_SET(death_test_style, "threadsafe");
796 
797   BackgroundThread background;
798   background.Start();
799 
800   // Main thread creates a Target object.
801   Target target;
802   // Main thread creates an arrow referencing the Target.
803   Arrow arrow;
804   arrow.target = target.AsWeakPtr();
805 
806   // Background copies the WeakPtr.
807   Arrow* arrow_copy;
808   background.CreateArrowFromArrow(&arrow_copy, &arrow);
809 
810   // The copy is still bound to main thread so I can deref.
811   EXPECT_EQ(arrow.target.get(), arrow_copy->target.get());
812 
813   // Although background thread created the copy, it can not deref the copied
814   // WeakPtr.
815   ASSERT_DCHECK_DEATH(background.DeRef(arrow_copy));
816 
817   background.DeleteArrow(arrow_copy);
818 }
819 
TEST(WeakPtrDeathTest,NonOwnerThreadDereferencesWeakPtrAfterReference)820 TEST(WeakPtrDeathTest, NonOwnerThreadDereferencesWeakPtrAfterReference) {
821   // The default style "fast" does not support multi-threaded tests
822   // (introduces deadlock on Linux).
823   GTEST_FLAG_SET(death_test_style, "threadsafe");
824 
825   // Main thread creates a Target object.
826   Target target;
827 
828   // Main thread creates an arrow referencing the Target (so target's
829   // thread ownership can not be implicitly moved).
830   Arrow arrow;
831   arrow.target = target.AsWeakPtr();
832   arrow.target.get();
833 
834   // Background thread tries to deref target, which violates thread ownership.
835   BackgroundThread background;
836   background.Start();
837   ASSERT_DCHECK_DEATH(background.DeRef(&arrow));
838 }
839 
TEST(WeakPtrDeathTest,NonOwnerThreadDeletesWeakPtrAfterReference)840 TEST(WeakPtrDeathTest, NonOwnerThreadDeletesWeakPtrAfterReference) {
841   // The default style "fast" does not support multi-threaded tests
842   // (introduces deadlock on Linux).
843   GTEST_FLAG_SET(death_test_style, "threadsafe");
844 
845   std::unique_ptr<Target> target(new Target());
846 
847   // Main thread creates an arrow referencing the Target.
848   Arrow arrow;
849   arrow.target = target->AsWeakPtr();
850 
851   // Background thread tries to deref target, binding it to the thread.
852   BackgroundThread background;
853   background.Start();
854   background.DeRef(&arrow);
855 
856   // Main thread deletes Target, violating thread binding.
857   ASSERT_DCHECK_DEATH(target.reset());
858 
859   // |target.reset()| died so |target| still holds the object, so we
860   // must pass it to the background thread to teardown.
861   background.DeleteTarget(target.release());
862 }
863 
TEST(WeakPtrDeathTest,NonOwnerThreadDeletesObjectAfterReference)864 TEST(WeakPtrDeathTest, NonOwnerThreadDeletesObjectAfterReference) {
865   // The default style "fast" does not support multi-threaded tests
866   // (introduces deadlock on Linux).
867   GTEST_FLAG_SET(death_test_style, "threadsafe");
868 
869   std::unique_ptr<Target> target(new Target());
870 
871   // Main thread creates an arrow referencing the Target, and references it, so
872   // that it becomes bound to the thread.
873   Arrow arrow;
874   arrow.target = target->AsWeakPtr();
875   arrow.target.get();
876 
877   // Background thread tries to delete target, volating thread binding.
878   BackgroundThread background;
879   background.Start();
880   ASSERT_DCHECK_DEATH(background.DeleteTarget(target.release()));
881 }
882 
TEST(WeakPtrDeathTest,NonOwnerThreadReferencesObjectAfterDeletion)883 TEST(WeakPtrDeathTest, NonOwnerThreadReferencesObjectAfterDeletion) {
884   // The default style "fast" does not support multi-threaded tests
885   // (introduces deadlock on Linux).
886   GTEST_FLAG_SET(death_test_style, "threadsafe");
887 
888   std::unique_ptr<Target> target(new Target());
889 
890   // Main thread creates an arrow referencing the Target.
891   Arrow arrow;
892   arrow.target = target->AsWeakPtr();
893 
894   // Background thread tries to delete target, binding the object to the thread.
895   BackgroundThread background;
896   background.Start();
897   background.DeleteTarget(target.release());
898 
899   // Main thread attempts to dereference the target, violating thread binding.
900   ASSERT_DCHECK_DEATH(arrow.target.get());
901 }
902 
TEST(WeakPtrDeathTest,ArrowOperatorChecksOnBadDereference)903 TEST(WeakPtrDeathTest, ArrowOperatorChecksOnBadDereference) {
904   // The default style "fast" does not support multi-threaded tests
905   // (introduces deadlock on Linux).
906   GTEST_FLAG_SET(death_test_style, "threadsafe");
907 
908   auto target = std::make_unique<Target>();
909   WeakPtr<Target> weak = target->AsWeakPtr();
910   target.reset();
911   EXPECT_CHECK_DEATH(weak->AsWeakPtr());
912 }
913 
TEST(WeakPtrDeathTest,StarOperatorChecksOnBadDereference)914 TEST(WeakPtrDeathTest, StarOperatorChecksOnBadDereference) {
915   // The default style "fast" does not support multi-threaded tests
916   // (introduces deadlock on Linux).
917   GTEST_FLAG_SET(death_test_style, "threadsafe");
918 
919   auto target = std::make_unique<Target>();
920   WeakPtr<Target> weak = target->AsWeakPtr();
921   target.reset();
922   EXPECT_CHECK_DEATH((*weak).AsWeakPtr());
923 }
924 
925 }  // namespace base
926