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