• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 The PDFium Authors
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/shared_copy_on_write.h"
6 
7 #include <map>
8 #include <string>
9 
10 #include "core/fxcrt/retain_ptr.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12 
13 namespace fxcrt {
14 namespace {
15 
16 class Observer {
17  public:
OnConstruct(const std::string & name)18   void OnConstruct(const std::string& name) { construction_counts_[name]++; }
OnDestruct(const std::string & name)19   void OnDestruct(const std::string& name) { destruction_counts_[name]++; }
GetConstructionCount(const std::string & name)20   int GetConstructionCount(const std::string& name) {
21     return construction_counts_[name];
22   }
GetDestructionCount(const std::string & name)23   int GetDestructionCount(const std::string& name) {
24     return destruction_counts_[name];
25   }
26 
27  private:
28   std::map<std::string, int> construction_counts_;
29   std::map<std::string, int> destruction_counts_;
30 };
31 
32 class Object final : public Retainable {
33  public:
34   CONSTRUCT_VIA_MAKE_RETAIN;
35 
Clone() const36   RetainPtr<Object> Clone() const { return pdfium::MakeRetain<Object>(*this); }
37 
38  private:
Object(Observer * observer,const std::string & name)39   Object(Observer* observer, const std::string& name)
40       : name_(name), observer_(observer) {
41     observer->OnConstruct(name_);
42   }
Object(const Object & that)43   Object(const Object& that) : name_(that.name_), observer_(that.observer_) {
44     observer_->OnConstruct(name_);
45   }
~Object()46   ~Object() override { observer_->OnDestruct(name_); }
47 
48   std::string name_;
49   Observer* observer_;
50 };
51 
52 }  // namespace
53 
TEST(SharedCopyOnWrite,Null)54 TEST(SharedCopyOnWrite, Null) {
55   Observer observer;
56   {
57     SharedCopyOnWrite<Object> ptr;
58     EXPECT_FALSE(ptr.GetObject());
59   }
60 }
61 
TEST(SharedCopyOnWrite,Copy)62 TEST(SharedCopyOnWrite, Copy) {
63   Observer observer;
64   {
65     SharedCopyOnWrite<Object> ptr1;
66     ptr1.Emplace(&observer, std::string("one"));
67     {
68       SharedCopyOnWrite<Object> ptr2 = ptr1;
69       EXPECT_EQ(1, observer.GetConstructionCount("one"));
70       EXPECT_EQ(0, observer.GetDestructionCount("one"));
71     }
72     {
73       SharedCopyOnWrite<Object> ptr3(ptr1);
74       EXPECT_EQ(1, observer.GetConstructionCount("one"));
75       EXPECT_EQ(0, observer.GetDestructionCount("one"));
76     }
77     EXPECT_EQ(1, observer.GetConstructionCount("one"));
78     EXPECT_EQ(0, observer.GetDestructionCount("one"));
79   }
80   EXPECT_EQ(1, observer.GetDestructionCount("one"));
81 }
82 
TEST(SharedCopyOnWrite,AssignOverOld)83 TEST(SharedCopyOnWrite, AssignOverOld) {
84   Observer observer;
85   {
86     SharedCopyOnWrite<Object> ptr1;
87     ptr1.Emplace(&observer, std::string("one"));
88     ptr1.Emplace(&observer, std::string("two"));
89     EXPECT_EQ(1, observer.GetConstructionCount("one"));
90     EXPECT_EQ(1, observer.GetConstructionCount("two"));
91     EXPECT_EQ(1, observer.GetDestructionCount("one"));
92     EXPECT_EQ(0, observer.GetDestructionCount("two"));
93   }
94   EXPECT_EQ(1, observer.GetDestructionCount("two"));
95 }
96 
TEST(SharedCopyOnWrite,AssignOverRetained)97 TEST(SharedCopyOnWrite, AssignOverRetained) {
98   Observer observer;
99   {
100     SharedCopyOnWrite<Object> ptr1;
101     ptr1.Emplace(&observer, std::string("one"));
102     SharedCopyOnWrite<Object> ptr2(ptr1);
103     ptr1.Emplace(&observer, std::string("two"));
104     EXPECT_EQ(1, observer.GetConstructionCount("one"));
105     EXPECT_EQ(1, observer.GetConstructionCount("two"));
106     EXPECT_EQ(0, observer.GetDestructionCount("one"));
107     EXPECT_EQ(0, observer.GetDestructionCount("two"));
108   }
109   EXPECT_EQ(1, observer.GetDestructionCount("one"));
110   EXPECT_EQ(1, observer.GetDestructionCount("two"));
111 }
112 
TEST(SharedCopyOnWrite,GetModify)113 TEST(SharedCopyOnWrite, GetModify) {
114   Observer observer;
115   {
116     SharedCopyOnWrite<Object> ptr;
117     EXPECT_TRUE(ptr.GetPrivateCopy(&observer, std::string("one")));
118     EXPECT_EQ(1, observer.GetConstructionCount("one"));
119     EXPECT_EQ(0, observer.GetDestructionCount("one"));
120 
121     EXPECT_TRUE(ptr.GetPrivateCopy(&observer, std::string("one")));
122     EXPECT_EQ(1, observer.GetConstructionCount("one"));
123     EXPECT_EQ(0, observer.GetDestructionCount("one"));
124     {
125       SharedCopyOnWrite<Object> other(ptr);
126       EXPECT_TRUE(ptr.GetPrivateCopy(&observer, std::string("one")));
127       EXPECT_EQ(2, observer.GetConstructionCount("one"));
128       EXPECT_EQ(0, observer.GetDestructionCount("one"));
129     }
130     EXPECT_EQ(2, observer.GetConstructionCount("one"));
131     EXPECT_EQ(1, observer.GetDestructionCount("one"));
132   }
133   EXPECT_EQ(2, observer.GetDestructionCount("one"));
134 }
135 
136 }  // namespace fxcrt
137