• 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/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:
Object(Observer * observer,const std::string & name)34   Object(Observer* observer, const std::string& name)
35       : name_(name), observer_(observer) {
36     observer->OnConstruct(name_);
37   }
Object(const Object & that)38   Object(const Object& that) : name_(that.name_), observer_(that.observer_) {
39     observer_->OnConstruct(name_);
40   }
~Object()41   ~Object() override { observer_->OnDestruct(name_); }
42 
Clone() const43   RetainPtr<Object> Clone() const { return pdfium::MakeRetain<Object>(*this); }
44 
45  private:
46   std::string name_;
47   Observer* observer_;
48 };
49 
50 }  // namespace
51 
TEST(SharedCopyOnWrite,Null)52 TEST(SharedCopyOnWrite, Null) {
53   Observer observer;
54   {
55     SharedCopyOnWrite<Object> ptr;
56     EXPECT_EQ(nullptr, ptr.GetObject());
57   }
58 }
59 
TEST(SharedCopyOnWrite,Copy)60 TEST(SharedCopyOnWrite, Copy) {
61   Observer observer;
62   {
63     SharedCopyOnWrite<Object> ptr1;
64     ptr1.Emplace(&observer, std::string("one"));
65     {
66       SharedCopyOnWrite<Object> ptr2 = ptr1;
67       EXPECT_EQ(1, observer.GetConstructionCount("one"));
68       EXPECT_EQ(0, observer.GetDestructionCount("one"));
69     }
70     {
71       SharedCopyOnWrite<Object> ptr3(ptr1);
72       EXPECT_EQ(1, observer.GetConstructionCount("one"));
73       EXPECT_EQ(0, observer.GetDestructionCount("one"));
74     }
75     EXPECT_EQ(1, observer.GetConstructionCount("one"));
76     EXPECT_EQ(0, observer.GetDestructionCount("one"));
77   }
78   EXPECT_EQ(1, observer.GetDestructionCount("one"));
79 }
80 
TEST(SharedCopyOnWrite,AssignOverOld)81 TEST(SharedCopyOnWrite, AssignOverOld) {
82   Observer observer;
83   {
84     SharedCopyOnWrite<Object> ptr1;
85     ptr1.Emplace(&observer, std::string("one"));
86     ptr1.Emplace(&observer, std::string("two"));
87     EXPECT_EQ(1, observer.GetConstructionCount("one"));
88     EXPECT_EQ(1, observer.GetConstructionCount("two"));
89     EXPECT_EQ(1, observer.GetDestructionCount("one"));
90     EXPECT_EQ(0, observer.GetDestructionCount("two"));
91   }
92   EXPECT_EQ(1, observer.GetDestructionCount("two"));
93 }
94 
TEST(SharedCopyOnWrite,AssignOverRetained)95 TEST(SharedCopyOnWrite, AssignOverRetained) {
96   Observer observer;
97   {
98     SharedCopyOnWrite<Object> ptr1;
99     ptr1.Emplace(&observer, std::string("one"));
100     SharedCopyOnWrite<Object> ptr2(ptr1);
101     ptr1.Emplace(&observer, std::string("two"));
102     EXPECT_EQ(1, observer.GetConstructionCount("one"));
103     EXPECT_EQ(1, observer.GetConstructionCount("two"));
104     EXPECT_EQ(0, observer.GetDestructionCount("one"));
105     EXPECT_EQ(0, observer.GetDestructionCount("two"));
106   }
107   EXPECT_EQ(1, observer.GetDestructionCount("one"));
108   EXPECT_EQ(1, observer.GetDestructionCount("two"));
109 }
110 
TEST(SharedCopyOnWrite,GetModify)111 TEST(SharedCopyOnWrite, GetModify) {
112   Observer observer;
113   {
114     SharedCopyOnWrite<Object> ptr;
115     EXPECT_NE(nullptr, ptr.GetPrivateCopy(&observer, std::string("one")));
116     EXPECT_EQ(1, observer.GetConstructionCount("one"));
117     EXPECT_EQ(0, observer.GetDestructionCount("one"));
118 
119     EXPECT_NE(nullptr, ptr.GetPrivateCopy(&observer, std::string("one")));
120     EXPECT_EQ(1, observer.GetConstructionCount("one"));
121     EXPECT_EQ(0, observer.GetDestructionCount("one"));
122     {
123       SharedCopyOnWrite<Object> other(ptr);
124       EXPECT_NE(nullptr, ptr.GetPrivateCopy(&observer, std::string("one")));
125       EXPECT_EQ(2, observer.GetConstructionCount("one"));
126       EXPECT_EQ(0, observer.GetDestructionCount("one"));
127     }
128     EXPECT_EQ(2, observer.GetConstructionCount("one"));
129     EXPECT_EQ(1, observer.GetDestructionCount("one"));
130   }
131   EXPECT_EQ(2, observer.GetDestructionCount("one"));
132 }
133 
134 }  // namespace fxcrt
135