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