Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(71)

Side by Side Diff: base/memory/weak_ptr_unittest.cc

Issue 1863643002: Add a std::nullptr_t constructor to base::WeakPtr. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: format Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/memory/weak_ptr.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/memory/weak_ptr.h" 5 #include "base/memory/weak_ptr.h"
6 6
7 #include <memory> 7 #include <memory>
8 #include <string> 8 #include <string>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/debug/leak_annotations.h" 11 #include "base/debug/leak_annotations.h"
12 #include "base/location.h" 12 #include "base/location.h"
13 #include "base/single_thread_task_runner.h" 13 #include "base/single_thread_task_runner.h"
14 #include "base/synchronization/waitable_event.h" 14 #include "base/synchronization/waitable_event.h"
15 #include "base/threading/thread.h" 15 #include "base/threading/thread.h"
16 #include "testing/gtest/include/gtest/gtest.h" 16 #include "testing/gtest/include/gtest/gtest.h"
17 17
18 namespace base { 18 namespace base {
19 namespace { 19 namespace {
20 20
21 WeakPtr<int> PassThru(WeakPtr<int> ptr) {
22 return ptr;
23 }
24
21 template <class T> 25 template <class T>
22 class OffThreadObjectCreator { 26 class OffThreadObjectCreator {
23 public: 27 public:
24 static T* NewObject() { 28 static T* NewObject() {
25 T* result; 29 T* result;
26 { 30 {
27 Thread creator_thread("creator_thread"); 31 Thread creator_thread("creator_thread");
28 creator_thread.Start(); 32 creator_thread.Start();
29 creator_thread.task_runner()->PostTask( 33 creator_thread.task_runner()->PostTask(
30 FROM_HERE, base::Bind(OffThreadObjectCreator::CreateObject, &result)); 34 FROM_HERE, base::Bind(OffThreadObjectCreator::CreateObject, &result));
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 void DeleteArrow(Arrow* object) { 111 void DeleteArrow(Arrow* object) {
108 WaitableEvent completion(true, false); 112 WaitableEvent completion(true, false);
109 task_runner()->PostTask( 113 task_runner()->PostTask(
110 FROM_HERE, 114 FROM_HERE,
111 base::Bind(&BackgroundThread::DoDeleteArrow, object, &completion)); 115 base::Bind(&BackgroundThread::DoDeleteArrow, object, &completion));
112 completion.Wait(); 116 completion.Wait();
113 } 117 }
114 118
115 Target* DeRef(const Arrow* arrow) { 119 Target* DeRef(const Arrow* arrow) {
116 WaitableEvent completion(true, false); 120 WaitableEvent completion(true, false);
117 Target* result = NULL; 121 Target* result = nullptr;
118 task_runner()->PostTask(FROM_HERE, base::Bind(&BackgroundThread::DoDeRef, 122 task_runner()->PostTask(FROM_HERE, base::Bind(&BackgroundThread::DoDeRef,
119 arrow, &result, &completion)); 123 arrow, &result, &completion));
120 completion.Wait(); 124 completion.Wait();
121 return result; 125 return result;
122 } 126 }
123 127
124 protected: 128 protected:
125 static void DoCreateArrowFromArrow(Arrow** arrow, 129 static void DoCreateArrowFromArrow(Arrow** arrow,
126 const Arrow* other, 130 const Arrow* other,
127 WaitableEvent* completion) { 131 WaitableEvent* completion) {
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 TEST(WeakPtrFactoryTest, Comparison) { 191 TEST(WeakPtrFactoryTest, Comparison) {
188 int data; 192 int data;
189 WeakPtrFactory<int> factory(&data); 193 WeakPtrFactory<int> factory(&data);
190 WeakPtr<int> ptr = factory.GetWeakPtr(); 194 WeakPtr<int> ptr = factory.GetWeakPtr();
191 WeakPtr<int> ptr2 = ptr; 195 WeakPtr<int> ptr2 = ptr;
192 EXPECT_EQ(ptr.get(), ptr2.get()); 196 EXPECT_EQ(ptr.get(), ptr2.get());
193 } 197 }
194 198
195 TEST(WeakPtrFactoryTest, OutOfScope) { 199 TEST(WeakPtrFactoryTest, OutOfScope) {
196 WeakPtr<int> ptr; 200 WeakPtr<int> ptr;
197 EXPECT_EQ(NULL, ptr.get()); 201 EXPECT_EQ(nullptr, ptr.get());
198 { 202 {
199 int data; 203 int data;
200 WeakPtrFactory<int> factory(&data); 204 WeakPtrFactory<int> factory(&data);
201 ptr = factory.GetWeakPtr(); 205 ptr = factory.GetWeakPtr();
202 } 206 }
203 EXPECT_EQ(NULL, ptr.get()); 207 EXPECT_EQ(nullptr, ptr.get());
204 } 208 }
205 209
206 TEST(WeakPtrFactoryTest, Multiple) { 210 TEST(WeakPtrFactoryTest, Multiple) {
207 WeakPtr<int> a, b; 211 WeakPtr<int> a, b;
208 { 212 {
209 int data; 213 int data;
210 WeakPtrFactory<int> factory(&data); 214 WeakPtrFactory<int> factory(&data);
211 a = factory.GetWeakPtr(); 215 a = factory.GetWeakPtr();
212 b = factory.GetWeakPtr(); 216 b = factory.GetWeakPtr();
213 EXPECT_EQ(&data, a.get()); 217 EXPECT_EQ(&data, a.get());
214 EXPECT_EQ(&data, b.get()); 218 EXPECT_EQ(&data, b.get());
215 } 219 }
216 EXPECT_EQ(NULL, a.get()); 220 EXPECT_EQ(nullptr, a.get());
217 EXPECT_EQ(NULL, b.get()); 221 EXPECT_EQ(nullptr, b.get());
218 } 222 }
219 223
220 TEST(WeakPtrFactoryTest, MultipleStaged) { 224 TEST(WeakPtrFactoryTest, MultipleStaged) {
221 WeakPtr<int> a; 225 WeakPtr<int> a;
222 { 226 {
223 int data; 227 int data;
224 WeakPtrFactory<int> factory(&data); 228 WeakPtrFactory<int> factory(&data);
225 a = factory.GetWeakPtr(); 229 a = factory.GetWeakPtr();
226 { 230 {
227 WeakPtr<int> b = factory.GetWeakPtr(); 231 WeakPtr<int> b = factory.GetWeakPtr();
228 } 232 }
229 EXPECT_TRUE(NULL != a.get()); 233 EXPECT_NE(nullptr, a.get());
230 } 234 }
231 EXPECT_EQ(NULL, a.get()); 235 EXPECT_EQ(nullptr, a.get());
232 } 236 }
233 237
234 TEST(WeakPtrFactoryTest, Dereference) { 238 TEST(WeakPtrFactoryTest, Dereference) {
235 Base data; 239 Base data;
236 data.member = "123456"; 240 data.member = "123456";
237 WeakPtrFactory<Base> factory(&data); 241 WeakPtrFactory<Base> factory(&data);
238 WeakPtr<Base> ptr = factory.GetWeakPtr(); 242 WeakPtr<Base> ptr = factory.GetWeakPtr();
239 EXPECT_EQ(&data, ptr.get()); 243 EXPECT_EQ(&data, ptr.get());
240 EXPECT_EQ(data.member, (*ptr).member); 244 EXPECT_EQ(data.member, (*ptr).member);
241 EXPECT_EQ(data.member, ptr->member); 245 EXPECT_EQ(data.member, ptr->member);
242 } 246 }
243 247
244 TEST(WeakPtrFactoryTest, UpCast) { 248 TEST(WeakPtrFactoryTest, UpCast) {
245 Derived data; 249 Derived data;
246 WeakPtrFactory<Derived> factory(&data); 250 WeakPtrFactory<Derived> factory(&data);
247 WeakPtr<Base> ptr = factory.GetWeakPtr(); 251 WeakPtr<Base> ptr = factory.GetWeakPtr();
248 ptr = factory.GetWeakPtr(); 252 ptr = factory.GetWeakPtr();
249 EXPECT_EQ(ptr.get(), &data); 253 EXPECT_EQ(ptr.get(), &data);
250 } 254 }
251 255
256 TEST(WeakPtrTest, ConstructFromNullptr) {
257 WeakPtr<int> ptr = PassThru(nullptr);
258 EXPECT_EQ(nullptr, ptr.get());
259 }
260
252 TEST(WeakPtrTest, SupportsWeakPtr) { 261 TEST(WeakPtrTest, SupportsWeakPtr) {
253 Target target; 262 Target target;
254 WeakPtr<Target> ptr = target.AsWeakPtr(); 263 WeakPtr<Target> ptr = target.AsWeakPtr();
255 EXPECT_EQ(&target, ptr.get()); 264 EXPECT_EQ(&target, ptr.get());
256 } 265 }
257 266
258 TEST(WeakPtrTest, DerivedTarget) { 267 TEST(WeakPtrTest, DerivedTarget) {
259 DerivedTarget target; 268 DerivedTarget target;
260 WeakPtr<DerivedTarget> ptr = AsWeakPtr(&target); 269 WeakPtr<DerivedTarget> ptr = AsWeakPtr(&target);
261 EXPECT_EQ(&target, ptr.get()); 270 EXPECT_EQ(&target, ptr.get());
(...skipping 30 matching lines...) Expand all
292 } 301 }
293 } 302 }
294 303
295 TEST(WeakPtrTest, InvalidateWeakPtrs) { 304 TEST(WeakPtrTest, InvalidateWeakPtrs) {
296 int data; 305 int data;
297 WeakPtrFactory<int> factory(&data); 306 WeakPtrFactory<int> factory(&data);
298 WeakPtr<int> ptr = factory.GetWeakPtr(); 307 WeakPtr<int> ptr = factory.GetWeakPtr();
299 EXPECT_EQ(&data, ptr.get()); 308 EXPECT_EQ(&data, ptr.get());
300 EXPECT_TRUE(factory.HasWeakPtrs()); 309 EXPECT_TRUE(factory.HasWeakPtrs());
301 factory.InvalidateWeakPtrs(); 310 factory.InvalidateWeakPtrs();
302 EXPECT_EQ(NULL, ptr.get()); 311 EXPECT_EQ(nullptr, ptr.get());
303 EXPECT_FALSE(factory.HasWeakPtrs()); 312 EXPECT_FALSE(factory.HasWeakPtrs());
304 313
305 // Test that the factory can create new weak pointers after a 314 // Test that the factory can create new weak pointers after a
306 // InvalidateWeakPtrs call, and they remain valid until the next 315 // InvalidateWeakPtrs call, and they remain valid until the next
307 // InvalidateWeakPtrs call. 316 // InvalidateWeakPtrs call.
308 WeakPtr<int> ptr2 = factory.GetWeakPtr(); 317 WeakPtr<int> ptr2 = factory.GetWeakPtr();
309 EXPECT_EQ(&data, ptr2.get()); 318 EXPECT_EQ(&data, ptr2.get());
310 EXPECT_TRUE(factory.HasWeakPtrs()); 319 EXPECT_TRUE(factory.HasWeakPtrs());
311 factory.InvalidateWeakPtrs(); 320 factory.InvalidateWeakPtrs();
312 EXPECT_EQ(NULL, ptr2.get()); 321 EXPECT_EQ(nullptr, ptr2.get());
313 EXPECT_FALSE(factory.HasWeakPtrs()); 322 EXPECT_FALSE(factory.HasWeakPtrs());
314 } 323 }
315 324
316 TEST(WeakPtrTest, HasWeakPtrs) { 325 TEST(WeakPtrTest, HasWeakPtrs) {
317 int data; 326 int data;
318 WeakPtrFactory<int> factory(&data); 327 WeakPtrFactory<int> factory(&data);
319 { 328 {
320 WeakPtr<int> ptr = factory.GetWeakPtr(); 329 WeakPtr<int> ptr = factory.GetWeakPtr();
321 EXPECT_TRUE(factory.HasWeakPtrs()); 330 EXPECT_TRUE(factory.HasWeakPtrs());
322 } 331 }
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 background.Start(); 418 background.Start();
410 419
411 Arrow arrow; 420 Arrow arrow;
412 std::unique_ptr<TargetWithFactory> target(new TargetWithFactory); 421 std::unique_ptr<TargetWithFactory> target(new TargetWithFactory);
413 422
414 // Bind to main thread. 423 // Bind to main thread.
415 arrow.target = target->factory.GetWeakPtr(); 424 arrow.target = target->factory.GetWeakPtr();
416 EXPECT_EQ(target.get(), arrow.target.get()); 425 EXPECT_EQ(target.get(), arrow.target.get());
417 426
418 target->factory.InvalidateWeakPtrs(); 427 target->factory.InvalidateWeakPtrs();
419 EXPECT_EQ(NULL, arrow.target.get()); 428 EXPECT_EQ(nullptr, arrow.target.get());
420 429
421 arrow.target = target->factory.GetWeakPtr(); 430 arrow.target = target->factory.GetWeakPtr();
422 // Re-bind to background thread. 431 // Re-bind to background thread.
423 EXPECT_EQ(target.get(), background.DeRef(&arrow)); 432 EXPECT_EQ(target.get(), background.DeRef(&arrow));
424 433
425 // And the background thread can now delete the target. 434 // And the background thread can now delete the target.
426 background.DeleteTarget(target.release()); 435 background.DeleteTarget(target.release());
427 } 436 }
428 437
429 TEST(WeakPtrTest, MainThreadRefOutlivesBackgroundThreadRef) { 438 TEST(WeakPtrTest, MainThreadRefOutlivesBackgroundThreadRef) {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
472 // - WeakPtr gets destroyed on Thread B 481 // - WeakPtr gets destroyed on Thread B
473 BackgroundThread background; 482 BackgroundThread background;
474 background.Start(); 483 background.Start();
475 Arrow* arrow_copy; 484 Arrow* arrow_copy;
476 { 485 {
477 Target target; 486 Target target;
478 Arrow arrow; 487 Arrow arrow;
479 arrow.target = target.AsWeakPtr(); 488 arrow.target = target.AsWeakPtr();
480 background.CreateArrowFromArrow(&arrow_copy, &arrow); 489 background.CreateArrowFromArrow(&arrow_copy, &arrow);
481 } 490 }
482 EXPECT_EQ(NULL, arrow_copy->target.get()); 491 EXPECT_EQ(nullptr, arrow_copy->target.get());
483 background.DeleteArrow(arrow_copy); 492 background.DeleteArrow(arrow_copy);
484 } 493 }
485 494
486 TEST(WeakPtrTest, NonOwnerThreadCanCopyAndAssignWeakPtr) { 495 TEST(WeakPtrTest, NonOwnerThreadCanCopyAndAssignWeakPtr) {
487 // Main thread creates a Target object. 496 // Main thread creates a Target object.
488 Target target; 497 Target target;
489 // Main thread creates an arrow referencing the Target. 498 // Main thread creates an arrow referencing the Target.
490 Arrow *arrow = new Arrow(); 499 Arrow *arrow = new Arrow();
491 arrow->target = target.AsWeakPtr(); 500 arrow->target = target.AsWeakPtr();
492 501
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
633 background.Start(); 642 background.Start();
634 background.DeleteTarget(target.release()); 643 background.DeleteTarget(target.release());
635 644
636 // Main thread attempts to dereference the target, violating thread binding. 645 // Main thread attempts to dereference the target, violating thread binding.
637 ASSERT_DEATH(arrow.target.get(), ""); 646 ASSERT_DEATH(arrow.target.get(), "");
638 } 647 }
639 648
640 #endif 649 #endif
641 650
642 } // namespace base 651 } // namespace base
OLDNEW
« no previous file with comments | « base/memory/weak_ptr.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698