xref: /aosp_15_r20/external/webrtc/rtc_base/weak_ptr_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright 2016 The WebRTC Project Authors. All rights reserved.
3*d9f75844SAndroid Build Coastguard Worker  *
4*d9f75844SAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker  */
10*d9f75844SAndroid Build Coastguard Worker 
11*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/weak_ptr.h"
12*d9f75844SAndroid Build Coastguard Worker 
13*d9f75844SAndroid Build Coastguard Worker #include <memory>
14*d9f75844SAndroid Build Coastguard Worker #include <string>
15*d9f75844SAndroid Build Coastguard Worker 
16*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/event.h"
17*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/task_queue_for_test.h"
18*d9f75844SAndroid Build Coastguard Worker #include "test/gtest.h"
19*d9f75844SAndroid Build Coastguard Worker 
20*d9f75844SAndroid Build Coastguard Worker namespace rtc {
21*d9f75844SAndroid Build Coastguard Worker 
22*d9f75844SAndroid Build Coastguard Worker namespace {
23*d9f75844SAndroid Build Coastguard Worker 
24*d9f75844SAndroid Build Coastguard Worker struct Base {
25*d9f75844SAndroid Build Coastguard Worker   std::string member;
26*d9f75844SAndroid Build Coastguard Worker };
27*d9f75844SAndroid Build Coastguard Worker struct Derived : public Base {};
28*d9f75844SAndroid Build Coastguard Worker 
29*d9f75844SAndroid Build Coastguard Worker struct Target {};
30*d9f75844SAndroid Build Coastguard Worker 
31*d9f75844SAndroid Build Coastguard Worker struct Arrow {
32*d9f75844SAndroid Build Coastguard Worker   WeakPtr<Target> target;
33*d9f75844SAndroid Build Coastguard Worker };
34*d9f75844SAndroid Build Coastguard Worker 
35*d9f75844SAndroid Build Coastguard Worker struct TargetWithFactory : public Target {
TargetWithFactoryrtc::__anon343dfe7f0111::TargetWithFactory36*d9f75844SAndroid Build Coastguard Worker   TargetWithFactory() : factory(this) {}
37*d9f75844SAndroid Build Coastguard Worker   WeakPtrFactory<Target> factory;
38*d9f75844SAndroid Build Coastguard Worker };
39*d9f75844SAndroid Build Coastguard Worker 
40*d9f75844SAndroid Build Coastguard Worker }  // namespace
41*d9f75844SAndroid Build Coastguard Worker 
TEST(WeakPtrFactoryTest,Basic)42*d9f75844SAndroid Build Coastguard Worker TEST(WeakPtrFactoryTest, Basic) {
43*d9f75844SAndroid Build Coastguard Worker   int data;
44*d9f75844SAndroid Build Coastguard Worker   WeakPtrFactory<int> factory(&data);
45*d9f75844SAndroid Build Coastguard Worker   WeakPtr<int> ptr = factory.GetWeakPtr();
46*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(&data, ptr.get());
47*d9f75844SAndroid Build Coastguard Worker }
48*d9f75844SAndroid Build Coastguard Worker 
TEST(WeakPtrFactoryTest,Comparison)49*d9f75844SAndroid Build Coastguard Worker TEST(WeakPtrFactoryTest, Comparison) {
50*d9f75844SAndroid Build Coastguard Worker   int data;
51*d9f75844SAndroid Build Coastguard Worker   WeakPtrFactory<int> factory(&data);
52*d9f75844SAndroid Build Coastguard Worker   WeakPtr<int> ptr = factory.GetWeakPtr();
53*d9f75844SAndroid Build Coastguard Worker   WeakPtr<int> ptr2 = ptr;
54*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(ptr.get(), ptr2.get());
55*d9f75844SAndroid Build Coastguard Worker }
56*d9f75844SAndroid Build Coastguard Worker 
TEST(WeakPtrFactoryTest,Move)57*d9f75844SAndroid Build Coastguard Worker TEST(WeakPtrFactoryTest, Move) {
58*d9f75844SAndroid Build Coastguard Worker   int data;
59*d9f75844SAndroid Build Coastguard Worker   WeakPtrFactory<int> factory(&data);
60*d9f75844SAndroid Build Coastguard Worker   WeakPtr<int> ptr = factory.GetWeakPtr();
61*d9f75844SAndroid Build Coastguard Worker   WeakPtr<int> ptr2 = factory.GetWeakPtr();
62*d9f75844SAndroid Build Coastguard Worker   WeakPtr<int> ptr3 = std::move(ptr2);
63*d9f75844SAndroid Build Coastguard Worker   EXPECT_NE(ptr.get(), ptr2.get());
64*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(ptr.get(), ptr3.get());
65*d9f75844SAndroid Build Coastguard Worker }
66*d9f75844SAndroid Build Coastguard Worker 
TEST(WeakPtrFactoryTest,OutOfScope)67*d9f75844SAndroid Build Coastguard Worker TEST(WeakPtrFactoryTest, OutOfScope) {
68*d9f75844SAndroid Build Coastguard Worker   WeakPtr<int> ptr;
69*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(nullptr, ptr.get());
70*d9f75844SAndroid Build Coastguard Worker   {
71*d9f75844SAndroid Build Coastguard Worker     int data;
72*d9f75844SAndroid Build Coastguard Worker     WeakPtrFactory<int> factory(&data);
73*d9f75844SAndroid Build Coastguard Worker     ptr = factory.GetWeakPtr();
74*d9f75844SAndroid Build Coastguard Worker     EXPECT_EQ(&data, ptr.get());
75*d9f75844SAndroid Build Coastguard Worker   }
76*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(nullptr, ptr.get());
77*d9f75844SAndroid Build Coastguard Worker }
78*d9f75844SAndroid Build Coastguard Worker 
TEST(WeakPtrFactoryTest,Multiple)79*d9f75844SAndroid Build Coastguard Worker TEST(WeakPtrFactoryTest, Multiple) {
80*d9f75844SAndroid Build Coastguard Worker   WeakPtr<int> a, b;
81*d9f75844SAndroid Build Coastguard Worker   {
82*d9f75844SAndroid Build Coastguard Worker     int data;
83*d9f75844SAndroid Build Coastguard Worker     WeakPtrFactory<int> factory(&data);
84*d9f75844SAndroid Build Coastguard Worker     a = factory.GetWeakPtr();
85*d9f75844SAndroid Build Coastguard Worker     b = factory.GetWeakPtr();
86*d9f75844SAndroid Build Coastguard Worker     EXPECT_EQ(&data, a.get());
87*d9f75844SAndroid Build Coastguard Worker     EXPECT_EQ(&data, b.get());
88*d9f75844SAndroid Build Coastguard Worker   }
89*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(nullptr, a.get());
90*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(nullptr, b.get());
91*d9f75844SAndroid Build Coastguard Worker }
92*d9f75844SAndroid Build Coastguard Worker 
TEST(WeakPtrFactoryTest,MultipleStaged)93*d9f75844SAndroid Build Coastguard Worker TEST(WeakPtrFactoryTest, MultipleStaged) {
94*d9f75844SAndroid Build Coastguard Worker   WeakPtr<int> a;
95*d9f75844SAndroid Build Coastguard Worker   {
96*d9f75844SAndroid Build Coastguard Worker     int data;
97*d9f75844SAndroid Build Coastguard Worker     WeakPtrFactory<int> factory(&data);
98*d9f75844SAndroid Build Coastguard Worker     a = factory.GetWeakPtr();
99*d9f75844SAndroid Build Coastguard Worker     { WeakPtr<int> b = factory.GetWeakPtr(); }
100*d9f75844SAndroid Build Coastguard Worker     EXPECT_NE(nullptr, a.get());
101*d9f75844SAndroid Build Coastguard Worker   }
102*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(nullptr, a.get());
103*d9f75844SAndroid Build Coastguard Worker }
104*d9f75844SAndroid Build Coastguard Worker 
TEST(WeakPtrFactoryTest,Dereference)105*d9f75844SAndroid Build Coastguard Worker TEST(WeakPtrFactoryTest, Dereference) {
106*d9f75844SAndroid Build Coastguard Worker   Base data;
107*d9f75844SAndroid Build Coastguard Worker   data.member = "123456";
108*d9f75844SAndroid Build Coastguard Worker   WeakPtrFactory<Base> factory(&data);
109*d9f75844SAndroid Build Coastguard Worker   WeakPtr<Base> ptr = factory.GetWeakPtr();
110*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(&data, ptr.get());
111*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(data.member, (*ptr).member);
112*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(data.member, ptr->member);
113*d9f75844SAndroid Build Coastguard Worker }
114*d9f75844SAndroid Build Coastguard Worker 
TEST(WeakPtrFactoryTest,UpCast)115*d9f75844SAndroid Build Coastguard Worker TEST(WeakPtrFactoryTest, UpCast) {
116*d9f75844SAndroid Build Coastguard Worker   Derived data;
117*d9f75844SAndroid Build Coastguard Worker   WeakPtrFactory<Derived> factory(&data);
118*d9f75844SAndroid Build Coastguard Worker   WeakPtr<Base> ptr = factory.GetWeakPtr();
119*d9f75844SAndroid Build Coastguard Worker   ptr = factory.GetWeakPtr();
120*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(ptr.get(), &data);
121*d9f75844SAndroid Build Coastguard Worker }
122*d9f75844SAndroid Build Coastguard Worker 
TEST(WeakPtrTest,DefaultConstructor)123*d9f75844SAndroid Build Coastguard Worker TEST(WeakPtrTest, DefaultConstructor) {
124*d9f75844SAndroid Build Coastguard Worker   WeakPtr<int> ptr;
125*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(nullptr, ptr.get());
126*d9f75844SAndroid Build Coastguard Worker }
127*d9f75844SAndroid Build Coastguard Worker 
TEST(WeakPtrFactoryTest,BooleanTesting)128*d9f75844SAndroid Build Coastguard Worker TEST(WeakPtrFactoryTest, BooleanTesting) {
129*d9f75844SAndroid Build Coastguard Worker   int data;
130*d9f75844SAndroid Build Coastguard Worker   WeakPtrFactory<int> factory(&data);
131*d9f75844SAndroid Build Coastguard Worker 
132*d9f75844SAndroid Build Coastguard Worker   WeakPtr<int> ptr_to_an_instance = factory.GetWeakPtr();
133*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(ptr_to_an_instance);
134*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(!ptr_to_an_instance);
135*d9f75844SAndroid Build Coastguard Worker 
136*d9f75844SAndroid Build Coastguard Worker   if (ptr_to_an_instance) {
137*d9f75844SAndroid Build Coastguard Worker   } else {
138*d9f75844SAndroid Build Coastguard Worker     ADD_FAILURE() << "Pointer to an instance should result in true.";
139*d9f75844SAndroid Build Coastguard Worker   }
140*d9f75844SAndroid Build Coastguard Worker 
141*d9f75844SAndroid Build Coastguard Worker   if (!ptr_to_an_instance) {  // check for operator!().
142*d9f75844SAndroid Build Coastguard Worker     ADD_FAILURE() << "Pointer to an instance should result in !x being false.";
143*d9f75844SAndroid Build Coastguard Worker   }
144*d9f75844SAndroid Build Coastguard Worker 
145*d9f75844SAndroid Build Coastguard Worker   WeakPtr<int> null_ptr;
146*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(null_ptr);
147*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(!null_ptr);
148*d9f75844SAndroid Build Coastguard Worker 
149*d9f75844SAndroid Build Coastguard Worker   if (null_ptr) {
150*d9f75844SAndroid Build Coastguard Worker     ADD_FAILURE() << "Null pointer should result in false.";
151*d9f75844SAndroid Build Coastguard Worker   }
152*d9f75844SAndroid Build Coastguard Worker 
153*d9f75844SAndroid Build Coastguard Worker   if (!null_ptr) {  // check for operator!().
154*d9f75844SAndroid Build Coastguard Worker   } else {
155*d9f75844SAndroid Build Coastguard Worker     ADD_FAILURE() << "Null pointer should result in !x being true.";
156*d9f75844SAndroid Build Coastguard Worker   }
157*d9f75844SAndroid Build Coastguard Worker }
158*d9f75844SAndroid Build Coastguard Worker 
TEST(WeakPtrFactoryTest,ComparisonToNull)159*d9f75844SAndroid Build Coastguard Worker TEST(WeakPtrFactoryTest, ComparisonToNull) {
160*d9f75844SAndroid Build Coastguard Worker   int data;
161*d9f75844SAndroid Build Coastguard Worker   WeakPtrFactory<int> factory(&data);
162*d9f75844SAndroid Build Coastguard Worker 
163*d9f75844SAndroid Build Coastguard Worker   WeakPtr<int> ptr_to_an_instance = factory.GetWeakPtr();
164*d9f75844SAndroid Build Coastguard Worker   EXPECT_NE(nullptr, ptr_to_an_instance);
165*d9f75844SAndroid Build Coastguard Worker   EXPECT_NE(ptr_to_an_instance, nullptr);
166*d9f75844SAndroid Build Coastguard Worker 
167*d9f75844SAndroid Build Coastguard Worker   WeakPtr<int> null_ptr;
168*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(null_ptr, nullptr);
169*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(nullptr, null_ptr);
170*d9f75844SAndroid Build Coastguard Worker }
171*d9f75844SAndroid Build Coastguard Worker 
TEST(WeakPtrTest,InvalidateWeakPtrs)172*d9f75844SAndroid Build Coastguard Worker TEST(WeakPtrTest, InvalidateWeakPtrs) {
173*d9f75844SAndroid Build Coastguard Worker   int data;
174*d9f75844SAndroid Build Coastguard Worker   WeakPtrFactory<int> factory(&data);
175*d9f75844SAndroid Build Coastguard Worker   WeakPtr<int> ptr = factory.GetWeakPtr();
176*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(&data, ptr.get());
177*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(factory.HasWeakPtrs());
178*d9f75844SAndroid Build Coastguard Worker   factory.InvalidateWeakPtrs();
179*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(nullptr, ptr.get());
180*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(factory.HasWeakPtrs());
181*d9f75844SAndroid Build Coastguard Worker 
182*d9f75844SAndroid Build Coastguard Worker   // Test that the factory can create new weak pointers after a
183*d9f75844SAndroid Build Coastguard Worker   // InvalidateWeakPtrs call, and they remain valid until the next
184*d9f75844SAndroid Build Coastguard Worker   // InvalidateWeakPtrs call.
185*d9f75844SAndroid Build Coastguard Worker   WeakPtr<int> ptr2 = factory.GetWeakPtr();
186*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(&data, ptr2.get());
187*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(factory.HasWeakPtrs());
188*d9f75844SAndroid Build Coastguard Worker   factory.InvalidateWeakPtrs();
189*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(nullptr, ptr2.get());
190*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(factory.HasWeakPtrs());
191*d9f75844SAndroid Build Coastguard Worker }
192*d9f75844SAndroid Build Coastguard Worker 
TEST(WeakPtrTest,HasWeakPtrs)193*d9f75844SAndroid Build Coastguard Worker TEST(WeakPtrTest, HasWeakPtrs) {
194*d9f75844SAndroid Build Coastguard Worker   int data;
195*d9f75844SAndroid Build Coastguard Worker   WeakPtrFactory<int> factory(&data);
196*d9f75844SAndroid Build Coastguard Worker   {
197*d9f75844SAndroid Build Coastguard Worker     WeakPtr<int> ptr = factory.GetWeakPtr();
198*d9f75844SAndroid Build Coastguard Worker     EXPECT_TRUE(factory.HasWeakPtrs());
199*d9f75844SAndroid Build Coastguard Worker   }
200*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(factory.HasWeakPtrs());
201*d9f75844SAndroid Build Coastguard Worker }
202*d9f75844SAndroid Build Coastguard Worker 
203*d9f75844SAndroid Build Coastguard Worker template <class T>
NewObjectCreatedOnTaskQueue()204*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<T> NewObjectCreatedOnTaskQueue() {
205*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<T> obj;
206*d9f75844SAndroid Build Coastguard Worker   webrtc::TaskQueueForTest queue("NewObjectCreatedOnTaskQueue");
207*d9f75844SAndroid Build Coastguard Worker   queue.SendTask([&] { obj = std::make_unique<T>(); });
208*d9f75844SAndroid Build Coastguard Worker   return obj;
209*d9f75844SAndroid Build Coastguard Worker }
210*d9f75844SAndroid Build Coastguard Worker 
TEST(WeakPtrTest,ObjectAndWeakPtrOnDifferentThreads)211*d9f75844SAndroid Build Coastguard Worker TEST(WeakPtrTest, ObjectAndWeakPtrOnDifferentThreads) {
212*d9f75844SAndroid Build Coastguard Worker   // Test that it is OK to create an object with a WeakPtrFactory one thread,
213*d9f75844SAndroid Build Coastguard Worker   // but use it on another.  This tests that we do not trip runtime checks that
214*d9f75844SAndroid Build Coastguard Worker   // ensure that a WeakPtr is not used by multiple threads.
215*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<TargetWithFactory> target(
216*d9f75844SAndroid Build Coastguard Worker       NewObjectCreatedOnTaskQueue<TargetWithFactory>());
217*d9f75844SAndroid Build Coastguard Worker   WeakPtr<Target> weak_ptr = target->factory.GetWeakPtr();
218*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(target.get(), weak_ptr.get());
219*d9f75844SAndroid Build Coastguard Worker }
220*d9f75844SAndroid Build Coastguard Worker 
TEST(WeakPtrTest,WeakPtrInitiateAndUseOnDifferentThreads)221*d9f75844SAndroid Build Coastguard Worker TEST(WeakPtrTest, WeakPtrInitiateAndUseOnDifferentThreads) {
222*d9f75844SAndroid Build Coastguard Worker   // Test that it is OK to create a WeakPtr on one thread, but use it on
223*d9f75844SAndroid Build Coastguard Worker   // another. This tests that we do not trip runtime checks that ensure that a
224*d9f75844SAndroid Build Coastguard Worker   // WeakPtr is not used by multiple threads.
225*d9f75844SAndroid Build Coastguard Worker   auto target = std::make_unique<TargetWithFactory>();
226*d9f75844SAndroid Build Coastguard Worker   // Create weak ptr on main thread
227*d9f75844SAndroid Build Coastguard Worker   WeakPtr<Target> weak_ptr = target->factory.GetWeakPtr();
228*d9f75844SAndroid Build Coastguard Worker   webrtc::TaskQueueForTest queue("queue");
229*d9f75844SAndroid Build Coastguard Worker   queue.SendTask([&] {
230*d9f75844SAndroid Build Coastguard Worker     // Dereference and invalide weak_ptr on another thread.
231*d9f75844SAndroid Build Coastguard Worker     EXPECT_EQ(weak_ptr.get(), target.get());
232*d9f75844SAndroid Build Coastguard Worker     target.reset();
233*d9f75844SAndroid Build Coastguard Worker   });
234*d9f75844SAndroid Build Coastguard Worker }
235*d9f75844SAndroid Build Coastguard Worker 
236*d9f75844SAndroid Build Coastguard Worker }  // namespace rtc
237