• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
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 "testing/gtest/include/gtest/gtest.h"
6 #include "base/thread.h"
7 #include "base/weak_ptr.h"
8 
9 namespace base {
10 namespace {
11 
12 template <class T>
13 class OffThreadObjectCreator {
14  public:
NewObject()15   static T* NewObject() {
16     T* result;
17     {
18       Thread creator_thread("creator_thread");
19       creator_thread.Start();
20       creator_thread.message_loop()->PostTask(FROM_HERE,
21           NewRunnableFunction(OffThreadObjectCreator::CreateObject, &result));
22     }
23     DCHECK(result);  // We synchronized on thread destruction above.
24     return result;
25   }
26  private:
CreateObject(T ** result)27   static void CreateObject(T** result) {
28     *result = new T;
29   }
30 };
31 
32 struct Base {};
33 struct Derived : Base {};
34 
35 struct Producer : SupportsWeakPtr<Producer> {};
36 struct Consumer { WeakPtr<Producer> producer; };
37 
38 }  // namespace
39 
TEST(WeakPtrTest,Basic)40 TEST(WeakPtrTest, Basic) {
41   int data;
42   WeakPtrFactory<int> factory(&data);
43   WeakPtr<int> ptr = factory.GetWeakPtr();
44   EXPECT_EQ(&data, ptr.get());
45 }
46 
TEST(WeakPtrTest,Comparison)47 TEST(WeakPtrTest, Comparison) {
48   int data;
49   WeakPtrFactory<int> factory(&data);
50   WeakPtr<int> ptr = factory.GetWeakPtr();
51   WeakPtr<int> ptr2 = ptr;
52   EXPECT_TRUE(ptr == ptr2);
53 }
54 
TEST(WeakPtrTest,OutOfScope)55 TEST(WeakPtrTest, OutOfScope) {
56   WeakPtr<int> ptr;
57   EXPECT_TRUE(ptr.get() == NULL);
58   {
59     int data;
60     WeakPtrFactory<int> factory(&data);
61     ptr = factory.GetWeakPtr();
62   }
63   EXPECT_TRUE(ptr.get() == NULL);
64 }
65 
TEST(WeakPtrTest,Multiple)66 TEST(WeakPtrTest, Multiple) {
67   WeakPtr<int> a, b;
68   {
69     int data;
70     WeakPtrFactory<int> factory(&data);
71     a = factory.GetWeakPtr();
72     b = factory.GetWeakPtr();
73     EXPECT_EQ(&data, a.get());
74     EXPECT_EQ(&data, b.get());
75   }
76   EXPECT_TRUE(a.get() == NULL);
77   EXPECT_TRUE(b.get() == NULL);
78 }
79 
TEST(WeakPtrTest,UpCast)80 TEST(WeakPtrTest, UpCast) {
81   Derived data;
82   WeakPtrFactory<Derived> factory(&data);
83   WeakPtr<Base> ptr = factory.GetWeakPtr();
84   ptr = factory.GetWeakPtr();
85   EXPECT_EQ(ptr.get(), &data);
86 }
87 
TEST(WeakPtrTest,SupportsWeakPtr)88 TEST(WeakPtrTest, SupportsWeakPtr) {
89   Producer f;
90   WeakPtr<Producer> ptr = f.AsWeakPtr();
91   EXPECT_EQ(&f, ptr.get());
92 }
93 
TEST(WeakPtrTest,InvalidateWeakPtrs)94 TEST(WeakPtrTest, InvalidateWeakPtrs) {
95   int data;
96   WeakPtrFactory<int> factory(&data);
97   WeakPtr<int> ptr = factory.GetWeakPtr();
98   EXPECT_EQ(&data, ptr.get());
99   EXPECT_TRUE(factory.HasWeakPtrs());
100   factory.InvalidateWeakPtrs();
101   EXPECT_TRUE(ptr.get() == NULL);
102   EXPECT_FALSE(factory.HasWeakPtrs());
103 }
104 
TEST(WeakPtrTest,HasWeakPtrs)105 TEST(WeakPtrTest, HasWeakPtrs) {
106   int data;
107   WeakPtrFactory<int> factory(&data);
108   {
109     WeakPtr<int> ptr = factory.GetWeakPtr();
110     EXPECT_TRUE(factory.HasWeakPtrs());
111   }
112   EXPECT_FALSE(factory.HasWeakPtrs());
113 }
114 
TEST(WeakPtrTest,SingleThreaded1)115 TEST(WeakPtrTest, SingleThreaded1) {
116   // Test that it is OK to create a class that supports weak references on one
117   // thread, but use it on another.  This tests that we do not trip runtime
118   // checks that ensure that a weak reference is not used by multiple threads.
119   scoped_ptr<Producer> producer(OffThreadObjectCreator<Producer>::NewObject());
120   WeakPtr<Producer> weak_producer = producer->AsWeakPtr();
121   EXPECT_EQ(producer.get(), weak_producer.get());
122 }
123 
TEST(WeakPtrTest,SingleThreaded2)124 TEST(WeakPtrTest, SingleThreaded2) {
125   // Test that it is OK to create a class that has a WeakPtr member on one
126   // thread, but use it on another.  This tests that we do not trip runtime
127   // checks that ensure that a weak reference is not used by multiple threads.
128   scoped_ptr<Consumer> consumer(OffThreadObjectCreator<Consumer>::NewObject());
129   Producer producer;
130   consumer->producer = producer.AsWeakPtr();
131   EXPECT_EQ(&producer, consumer->producer.get());
132 }
133 
134 }  // namespace base
135