OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <stddef.h> | 5 #include <stddef.h> |
6 | 6 |
7 #include "base/at_exit.h" | 7 #include "base/at_exit.h" |
8 #include "base/atomic_sequence_num.h" | 8 #include "base/atomic_sequence_num.h" |
9 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
10 #include "base/memory/aligned_memory.h" | 10 #include "base/memory/aligned_memory.h" |
(...skipping 27 matching lines...) Expand all Loading... |
38 | 38 |
39 static int constructed; | 39 static int constructed; |
40 private: | 40 private: |
41 int some_int_; | 41 int some_int_; |
42 }; | 42 }; |
43 | 43 |
44 int SlowConstructor::constructed = 0; | 44 int SlowConstructor::constructed = 0; |
45 | 45 |
46 class SlowDelegate : public base::DelegateSimpleThread::Delegate { | 46 class SlowDelegate : public base::DelegateSimpleThread::Delegate { |
47 public: | 47 public: |
48 explicit SlowDelegate(base::LazyInstance<SlowConstructor>* lazy) | 48 explicit SlowDelegate( |
| 49 base::LazyInstance<SlowConstructor>::DestructorAtExit* lazy) |
49 : lazy_(lazy) {} | 50 : lazy_(lazy) {} |
50 | 51 |
51 void Run() override { | 52 void Run() override { |
52 EXPECT_EQ(12, lazy_->Get().some_int()); | 53 EXPECT_EQ(12, lazy_->Get().some_int()); |
53 EXPECT_EQ(12, lazy_->Pointer()->some_int()); | 54 EXPECT_EQ(12, lazy_->Pointer()->some_int()); |
54 } | 55 } |
55 | 56 |
56 private: | 57 private: |
57 base::LazyInstance<SlowConstructor>* lazy_; | 58 base::LazyInstance<SlowConstructor>::DestructorAtExit* lazy_; |
58 }; | 59 }; |
59 | 60 |
60 } // namespace | 61 } // namespace |
61 | 62 |
62 static base::LazyInstance<ConstructAndDestructLogger> lazy_logger = | 63 static base::LazyInstance<ConstructAndDestructLogger>::DestructorAtExit |
63 LAZY_INSTANCE_INITIALIZER; | 64 lazy_logger = LAZY_INSTANCE_INITIALIZER; |
64 | 65 |
65 TEST(LazyInstanceTest, Basic) { | 66 TEST(LazyInstanceTest, Basic) { |
66 { | 67 { |
67 base::ShadowingAtExitManager shadow; | 68 base::ShadowingAtExitManager shadow; |
68 | 69 |
69 EXPECT_EQ(0, constructed_seq_.GetNext()); | 70 EXPECT_EQ(0, constructed_seq_.GetNext()); |
70 EXPECT_EQ(0, destructed_seq_.GetNext()); | 71 EXPECT_EQ(0, destructed_seq_.GetNext()); |
71 | 72 |
72 lazy_logger.Get(); | 73 lazy_logger.Get(); |
73 EXPECT_EQ(2, constructed_seq_.GetNext()); | 74 EXPECT_EQ(2, constructed_seq_.GetNext()); |
74 EXPECT_EQ(1, destructed_seq_.GetNext()); | 75 EXPECT_EQ(1, destructed_seq_.GetNext()); |
75 | 76 |
76 lazy_logger.Pointer(); | 77 lazy_logger.Pointer(); |
77 EXPECT_EQ(3, constructed_seq_.GetNext()); | 78 EXPECT_EQ(3, constructed_seq_.GetNext()); |
78 EXPECT_EQ(2, destructed_seq_.GetNext()); | 79 EXPECT_EQ(2, destructed_seq_.GetNext()); |
79 } | 80 } |
80 EXPECT_EQ(4, constructed_seq_.GetNext()); | 81 EXPECT_EQ(4, constructed_seq_.GetNext()); |
81 EXPECT_EQ(4, destructed_seq_.GetNext()); | 82 EXPECT_EQ(4, destructed_seq_.GetNext()); |
82 } | 83 } |
83 | 84 |
84 static base::LazyInstance<SlowConstructor> lazy_slow = | 85 static base::LazyInstance<SlowConstructor>::DestructorAtExit lazy_slow = |
85 LAZY_INSTANCE_INITIALIZER; | 86 LAZY_INSTANCE_INITIALIZER; |
86 | 87 |
87 TEST(LazyInstanceTest, ConstructorThreadSafety) { | 88 TEST(LazyInstanceTest, ConstructorThreadSafety) { |
88 { | 89 { |
89 base::ShadowingAtExitManager shadow; | 90 base::ShadowingAtExitManager shadow; |
90 | 91 |
91 SlowDelegate delegate(&lazy_slow); | 92 SlowDelegate delegate(&lazy_slow); |
92 EXPECT_EQ(0, SlowConstructor::constructed); | 93 EXPECT_EQ(0, SlowConstructor::constructed); |
93 | 94 |
94 base::DelegateSimpleThreadPool pool("lazy_instance_cons", 5); | 95 base::DelegateSimpleThreadPool pool("lazy_instance_cons", 5); |
(...skipping 24 matching lines...) Expand all Loading... |
119 }; | 120 }; |
120 | 121 |
121 } // anonymous namespace | 122 } // anonymous namespace |
122 | 123 |
123 TEST(LazyInstanceTest, LeakyLazyInstance) { | 124 TEST(LazyInstanceTest, LeakyLazyInstance) { |
124 // Check that using a plain LazyInstance causes the dtor to run | 125 // Check that using a plain LazyInstance causes the dtor to run |
125 // when the AtExitManager finishes. | 126 // when the AtExitManager finishes. |
126 bool deleted1 = false; | 127 bool deleted1 = false; |
127 { | 128 { |
128 base::ShadowingAtExitManager shadow; | 129 base::ShadowingAtExitManager shadow; |
129 static base::LazyInstance<DeleteLogger> test = LAZY_INSTANCE_INITIALIZER; | 130 static base::LazyInstance<DeleteLogger>::DestructorAtExit test = |
| 131 LAZY_INSTANCE_INITIALIZER; |
130 test.Get().SetDeletedPtr(&deleted1); | 132 test.Get().SetDeletedPtr(&deleted1); |
131 } | 133 } |
132 EXPECT_TRUE(deleted1); | 134 EXPECT_TRUE(deleted1); |
133 | 135 |
134 // Check that using a *leaky* LazyInstance makes the dtor not run | 136 // Check that using a *leaky* LazyInstance makes the dtor not run |
135 // when the AtExitManager finishes. | 137 // when the AtExitManager finishes. |
136 bool deleted2 = false; | 138 bool deleted2 = false; |
137 { | 139 { |
138 base::ShadowingAtExitManager shadow; | 140 base::ShadowingAtExitManager shadow; |
139 static base::LazyInstance<DeleteLogger>::Leaky | 141 static base::LazyInstance<DeleteLogger>::Leaky |
(...skipping 17 matching lines...) Expand all Loading... |
157 | 159 |
158 #define EXPECT_ALIGNED(ptr, align) \ | 160 #define EXPECT_ALIGNED(ptr, align) \ |
159 EXPECT_EQ(0u, reinterpret_cast<uintptr_t>(ptr) & (align - 1)) | 161 EXPECT_EQ(0u, reinterpret_cast<uintptr_t>(ptr) & (align - 1)) |
160 | 162 |
161 TEST(LazyInstanceTest, Alignment) { | 163 TEST(LazyInstanceTest, Alignment) { |
162 using base::LazyInstance; | 164 using base::LazyInstance; |
163 | 165 |
164 // Create some static instances with increasing sizes and alignment | 166 // Create some static instances with increasing sizes and alignment |
165 // requirements. By ordering this way, the linker will need to do some work to | 167 // requirements. By ordering this way, the linker will need to do some work to |
166 // ensure proper alignment of the static data. | 168 // ensure proper alignment of the static data. |
167 static LazyInstance<AlignedData<4> > align4 = LAZY_INSTANCE_INITIALIZER; | 169 static LazyInstance<AlignedData<4>>::DestructorAtExit align4 = |
168 static LazyInstance<AlignedData<32> > align32 = LAZY_INSTANCE_INITIALIZER; | 170 LAZY_INSTANCE_INITIALIZER; |
169 static LazyInstance<AlignedData<4096> > align4096 = LAZY_INSTANCE_INITIALIZER; | 171 static LazyInstance<AlignedData<32>>::DestructorAtExit align32 = |
| 172 LAZY_INSTANCE_INITIALIZER; |
| 173 static LazyInstance<AlignedData<4096>>::DestructorAtExit align4096 = |
| 174 LAZY_INSTANCE_INITIALIZER; |
170 | 175 |
171 EXPECT_ALIGNED(align4.Pointer(), 4); | 176 EXPECT_ALIGNED(align4.Pointer(), 4); |
172 EXPECT_ALIGNED(align32.Pointer(), 32); | 177 EXPECT_ALIGNED(align32.Pointer(), 32); |
173 EXPECT_ALIGNED(align4096.Pointer(), 4096); | 178 EXPECT_ALIGNED(align4096.Pointer(), 4096); |
174 } | 179 } |
OLD | NEW |