| 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 |