fix flaky ConnectTFOTimeout and ConnectTFOFallbackTimeout tests
[folly.git] / folly / test / ArenaSmartPtrTest.cpp
1 /*
2  * Copyright 2016 Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /*
18  * @author: Marcelo Juchem <marcelo@fb.com>
19  */
20
21 #include <folly/Memory.h>
22 #include <folly/Arena.h>
23
24 #include <gtest/gtest.h>
25
26 using namespace folly;
27
28 static_assert(
29   is_simple_allocator<int,SysArena>::value,
30   "SysArena should be a simple allocator"
31 );
32
33 struct global_counter {
34   global_counter(): count_(0) {}
35
36   void increase() { ++count_; }
37   void decrease() {
38     EXPECT_GT(count_, 0);
39     --count_;
40   }
41
42   unsigned count() const { return count_; }
43
44 private:
45   unsigned count_;
46 };
47
48 struct Foo {
49   explicit Foo(global_counter& counter):
50     counter_(counter)
51   {
52     counter_.increase();
53   }
54
55   ~Foo() {
56     counter_.decrease();
57   }
58
59 private:
60   global_counter& counter_;
61 };
62
63 template <typename Allocator>
64 void unique_ptr_test(Allocator& allocator) {
65   typedef typename AllocatorUniquePtr<Foo, Allocator>::type ptr_type;
66
67   global_counter counter;
68   EXPECT_EQ(counter.count(), 0);
69
70   Foo* foo = nullptr;
71
72   {
73     auto p = folly::allocate_unique<Foo>(allocator, counter);
74     EXPECT_EQ(counter.count(), 1);
75
76     p.reset();
77     EXPECT_EQ(counter.count(), 0);
78
79     p = folly::allocate_unique<Foo>(allocator, counter);
80     EXPECT_EQ(counter.count(), 1);
81
82     foo = p.release();
83     EXPECT_EQ(counter.count(), 1);
84   }
85   EXPECT_EQ(counter.count(), 1);
86
87   {
88     auto p = folly::allocate_unique<Foo>(allocator, counter);
89     EXPECT_EQ(counter.count(), 2);
90
91     [&](ptr_type g) {
92       EXPECT_EQ(counter.count(), 2);
93       g.reset();
94       EXPECT_EQ(counter.count(), 1);
95     }(std::move(p));
96   }
97   EXPECT_EQ(counter.count(), 1);
98
99   StlAllocator<Allocator, Foo>().destroy(foo);
100   EXPECT_EQ(counter.count(), 0);
101 }
102
103 TEST(ArenaSmartPtr, unique_ptr_SysArena) {
104   SysArena arena;
105   unique_ptr_test(arena);
106 }
107
108 TEST(ArenaSmartPtr, unique_ptr_StlAlloc_SysArena) {
109   SysArena arena;
110   StlAllocator<SysArena, Foo> alloc(&arena);
111   unique_ptr_test(alloc);
112 }
113
114 template <typename Allocator>
115 void shared_ptr_test(Allocator& allocator) {
116   typedef std::shared_ptr<Foo> ptr_type;
117
118   global_counter counter;
119   EXPECT_EQ(counter.count(), 0);
120
121   ptr_type foo;
122   EXPECT_EQ(counter.count(), 0);
123   EXPECT_EQ(foo.use_count(), 0);
124
125   {
126     auto p = folly::allocate_shared<Foo>(allocator, counter);
127     EXPECT_EQ(counter.count(), 1);
128     EXPECT_EQ(p.use_count(), 1);
129
130     p.reset();
131     EXPECT_EQ(counter.count(), 0);
132     EXPECT_EQ(p.use_count(), 0);
133
134     p = folly::allocate_shared<Foo>(allocator, counter);
135     EXPECT_EQ(counter.count(), 1);
136     EXPECT_EQ(p.use_count(), 1);
137
138     foo = p;
139     EXPECT_EQ(p.use_count(), 2);
140   }
141   EXPECT_EQ(counter.count(), 1);
142   EXPECT_EQ(foo.use_count(), 1);
143
144   {
145     auto p = foo;
146     EXPECT_EQ(counter.count(), 1);
147     EXPECT_EQ(p.use_count(), 2);
148
149     [&](ptr_type g) {
150       EXPECT_EQ(counter.count(), 1);
151       EXPECT_EQ(p.use_count(), 3);
152       EXPECT_EQ(g.use_count(), 3);
153       g.reset();
154       EXPECT_EQ(counter.count(), 1);
155       EXPECT_EQ(p.use_count(), 2);
156       EXPECT_EQ(g.use_count(), 0);
157     }(p);
158     EXPECT_EQ(counter.count(), 1);
159     EXPECT_EQ(p.use_count(), 2);
160   }
161   EXPECT_EQ(counter.count(), 1);
162   EXPECT_EQ(foo.use_count(), 1);
163
164   foo.reset();
165   EXPECT_EQ(counter.count(), 0);
166   EXPECT_EQ(foo.use_count(), 0);
167 }
168
169 TEST(ArenaSmartPtr, shared_ptr_SysArena) {
170   SysArena arena;
171   shared_ptr_test(arena);
172 }
173
174 TEST(ArenaSmartPtr, shared_ptr_StlAlloc_SysArena) {
175   SysArena arena;
176   StlAllocator<SysArena, Foo> alloc(&arena);
177   shared_ptr_test(alloc);
178 }
179
180 int main(int argc, char *argv[]) {
181   testing::InitGoogleTest(&argc, argv);
182   return RUN_ALL_TESTS();
183 }