• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 PDFium 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 "core/fxcrt/cfx_weak_ptr.h"
6 
7 #include <memory>
8 #include <utility>
9 
10 #include "core/fxcrt/fx_memory.h"
11 #include "testing/fx_string_testhelpers.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 
14 namespace {
15 
16 class PseudoDeletable;
17 using WeakPtr = CFX_WeakPtr<PseudoDeletable, ReleaseDeleter<PseudoDeletable>>;
18 using UniquePtr =
19     std::unique_ptr<PseudoDeletable, ReleaseDeleter<PseudoDeletable>>;
20 
21 class PseudoDeletable {
22  public:
PseudoDeletable()23   PseudoDeletable() : delete_count_(0) {}
Release()24   void Release() {
25     ++delete_count_;
26     next_.Reset();
27   }
SetNext(const WeakPtr & next)28   void SetNext(const WeakPtr& next) { next_ = next; }
delete_count() const29   int delete_count() const { return delete_count_; }
30 
31  private:
32   int delete_count_;
33   WeakPtr next_;
34 };
35 
36 }  // namespace
37 
TEST(fxcrt,WeakPtrNull)38 TEST(fxcrt, WeakPtrNull) {
39   WeakPtr ptr1;
40   EXPECT_FALSE(ptr1);
41 
42   WeakPtr ptr2;
43   EXPECT_TRUE(ptr1 == ptr2);
44   EXPECT_FALSE(ptr1 != ptr2);
45 
46   WeakPtr ptr3(ptr1);
47   EXPECT_TRUE(ptr1 == ptr3);
48   EXPECT_FALSE(ptr1 != ptr3);
49 
50   WeakPtr ptr4 = ptr1;
51   EXPECT_TRUE(ptr1 == ptr4);
52   EXPECT_FALSE(ptr1 != ptr4);
53 }
54 
TEST(fxcrt,WeakPtrNonNull)55 TEST(fxcrt, WeakPtrNonNull) {
56   PseudoDeletable thing;
57   EXPECT_EQ(0, thing.delete_count());
58   {
59     UniquePtr unique(&thing);
60     WeakPtr ptr1(std::move(unique));
61     EXPECT_TRUE(ptr1);
62     EXPECT_EQ(&thing, ptr1.Get());
63 
64     WeakPtr ptr2;
65     EXPECT_FALSE(ptr1 == ptr2);
66     EXPECT_TRUE(ptr1 != ptr2);
67     {
68       WeakPtr ptr3(ptr1);
69       EXPECT_TRUE(ptr1 == ptr3);
70       EXPECT_FALSE(ptr1 != ptr3);
71       EXPECT_EQ(&thing, ptr3.Get());
72       {
73         WeakPtr ptr4 = ptr1;
74         EXPECT_TRUE(ptr1 == ptr4);
75         EXPECT_FALSE(ptr1 != ptr4);
76         EXPECT_EQ(&thing, ptr4.Get());
77       }
78     }
79     EXPECT_EQ(0, thing.delete_count());
80   }
81   EXPECT_EQ(1, thing.delete_count());
82 }
83 
TEST(fxcrt,WeakPtrResetNull)84 TEST(fxcrt, WeakPtrResetNull) {
85   PseudoDeletable thing;
86   {
87     UniquePtr unique(&thing);
88     WeakPtr ptr1(std::move(unique));
89     WeakPtr ptr2 = ptr1;
90     ptr1.Reset();
91     EXPECT_FALSE(ptr1);
92     EXPECT_EQ(nullptr, ptr1.Get());
93     EXPECT_TRUE(ptr2);
94     EXPECT_EQ(&thing, ptr2.Get());
95     EXPECT_FALSE(ptr1 == ptr2);
96     EXPECT_TRUE(ptr1 != ptr2);
97     EXPECT_EQ(0, thing.delete_count());
98   }
99   EXPECT_EQ(1, thing.delete_count());
100 }
101 
TEST(fxcrt,WeakPtrResetNonNull)102 TEST(fxcrt, WeakPtrResetNonNull) {
103   PseudoDeletable thing1;
104   PseudoDeletable thing2;
105   {
106     UniquePtr unique1(&thing1);
107     WeakPtr ptr1(std::move(unique1));
108     WeakPtr ptr2 = ptr1;
109     UniquePtr unique2(&thing2);
110     ptr2.Reset(std::move(unique2));
111     EXPECT_TRUE(ptr1);
112     EXPECT_EQ(&thing1, ptr1.Get());
113     EXPECT_TRUE(ptr2);
114     EXPECT_EQ(&thing2, ptr2.Get());
115     EXPECT_FALSE(ptr1 == ptr2);
116     EXPECT_TRUE(ptr1 != ptr2);
117     EXPECT_EQ(0, thing1.delete_count());
118     EXPECT_EQ(0, thing2.delete_count());
119   }
120   EXPECT_EQ(1, thing1.delete_count());
121   EXPECT_EQ(1, thing2.delete_count());
122 }
123 
TEST(fxcrt,WeakPtrDeleteObject)124 TEST(fxcrt, WeakPtrDeleteObject) {
125   PseudoDeletable thing;
126   {
127     UniquePtr unique(&thing);
128     WeakPtr ptr1(std::move(unique));
129     WeakPtr ptr2 = ptr1;
130     ptr1.DeleteObject();
131     EXPECT_FALSE(ptr1);
132     EXPECT_EQ(nullptr, ptr1.Get());
133     EXPECT_FALSE(ptr2);
134     EXPECT_EQ(nullptr, ptr2.Get());
135     EXPECT_FALSE(ptr1 == ptr2);
136     EXPECT_TRUE(ptr1 != ptr2);
137     EXPECT_EQ(1, thing.delete_count());
138   }
139   EXPECT_EQ(1, thing.delete_count());
140 }
141 
TEST(fxcrt,WeakPtrCyclic)142 TEST(fxcrt, WeakPtrCyclic) {
143   PseudoDeletable thing1;
144   PseudoDeletable thing2;
145   {
146     UniquePtr unique1(&thing1);
147     UniquePtr unique2(&thing2);
148     WeakPtr ptr1(std::move(unique1));
149     WeakPtr ptr2(std::move(unique2));
150     ptr1->SetNext(ptr2);
151     ptr2->SetNext(ptr1);
152   }
153   // Leaks without explicit clear.
154   EXPECT_EQ(0, thing1.delete_count());
155   EXPECT_EQ(0, thing2.delete_count());
156 }
157 
TEST(fxcrt,WeakPtrCyclicDeleteObject)158 TEST(fxcrt, WeakPtrCyclicDeleteObject) {
159   PseudoDeletable thing1;
160   PseudoDeletable thing2;
161   {
162     UniquePtr unique1(&thing1);
163     UniquePtr unique2(&thing2);
164     WeakPtr ptr1(std::move(unique1));
165     WeakPtr ptr2(std::move(unique2));
166     ptr1->SetNext(ptr2);
167     ptr2->SetNext(ptr1);
168     ptr1.DeleteObject();
169     EXPECT_EQ(1, thing1.delete_count());
170     EXPECT_EQ(0, thing2.delete_count());
171   }
172   EXPECT_EQ(1, thing1.delete_count());
173   EXPECT_EQ(1, thing2.delete_count());
174 }
175