1 // Copyright 2012 The Chromium 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 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! DEPRECATED !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 6 // Please don't introduce new instances of LazyInstance<T>. Use a function-local 7 // static of type base::NoDestructor<T> instead: 8 // 9 // Factory& Factory::GetInstance() { 10 // static base::NoDestructor<Factory> instance; 11 // return *instance; 12 // } 13 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 14 // 15 // The LazyInstance<Type, Traits> class manages a single instance of Type, 16 // which will be lazily created on the first time it's accessed. This class is 17 // useful for places you would normally use a function-level static, but you 18 // need to have guaranteed thread-safety. The Type constructor will only ever 19 // be called once, even if two threads are racing to create the object. Get() 20 // and Pointer() will always return the same, completely initialized instance. 21 // When the instance is constructed it is registered with AtExitManager. The 22 // destructor will be called on program exit. 23 // 24 // LazyInstance is completely thread safe, assuming that you create it safely. 25 // The class was designed to be POD initialized, so it shouldn't require a 26 // static constructor. It really only makes sense to declare a LazyInstance as 27 // a global variable using the LAZY_INSTANCE_INITIALIZER initializer. 28 // 29 // LazyInstance is similar to Singleton, except it does not have the singleton 30 // property. You can have multiple LazyInstance's of the same type, and each 31 // will manage a unique instance. It also preallocates the space for Type, as 32 // to avoid allocating the Type instance on the heap. This may help with the 33 // performance of creating the instance, and reducing heap fragmentation. This 34 // requires that Type be a complete type so we can determine the size. 35 // 36 // Example usage: 37 // static LazyInstance<MyClass>::Leaky inst = LAZY_INSTANCE_INITIALIZER; 38 // void SomeMethod() { 39 // inst.Get().SomeMethod(); // MyClass::SomeMethod() 40 // 41 // MyClass* ptr = inst.Pointer(); 42 // ptr->DoDoDo(); // MyClass::DoDoDo 43 // } 44 45 #ifndef BASE_LAZY_INSTANCE_H_ 46 #define BASE_LAZY_INSTANCE_H_ 47 48 #include <atomic> 49 #include <new> // For placement new. 50 51 #include "base/check_op.h" 52 #include "base/dcheck_is_on.h" 53 #include "base/debug/leak_annotations.h" 54 #include "base/lazy_instance_helpers.h" 55 #include "base/threading/thread_restrictions.h" 56 #include "build/build_config.h" 57 58 // LazyInstance uses its own struct initializer-list style static 59 // initialization, which does not require a constructor. 60 #define LAZY_INSTANCE_INITIALIZER {} 61 62 namespace base { 63 64 template <typename Type> 65 struct LazyInstanceTraitsBase { NewLazyInstanceTraitsBase66 static Type* New(void* instance) { 67 DCHECK_EQ(reinterpret_cast<uintptr_t>(instance) & (alignof(Type) - 1), 0u); 68 // Use placement new to initialize our instance in our preallocated space. 69 // The parenthesis is very important here to force POD type initialization. 70 return new (instance) Type(); 71 } 72 CallDestructorLazyInstanceTraitsBase73 static void CallDestructor(Type* instance) { 74 // Explicitly call the destructor. 75 instance->~Type(); 76 } 77 }; 78 79 // We pull out some of the functionality into non-templated functions, so we 80 // can implement the more complicated pieces out of line in the .cc file. 81 namespace internal { 82 83 // This traits class causes destruction the contained Type at process exit via 84 // AtExitManager. This is probably generally not what you want. Instead, prefer 85 // Leaky below. 86 template <typename Type> 87 struct DestructorAtExitLazyInstanceTraits { 88 static const bool kRegisterOnExit = true; 89 #if DCHECK_IS_ON() 90 static const bool kAllowedToAccessOnNonjoinableThread = false; 91 #endif 92 NewDestructorAtExitLazyInstanceTraits93 static Type* New(void* instance) { 94 return LazyInstanceTraitsBase<Type>::New(instance); 95 } 96 DeleteDestructorAtExitLazyInstanceTraits97 static void Delete(Type* instance) { 98 LazyInstanceTraitsBase<Type>::CallDestructor(instance); 99 } 100 }; 101 102 // Use LazyInstance<T>::Leaky for a less-verbose call-site typedef; e.g.: 103 // base::LazyInstance<T>::Leaky my_leaky_lazy_instance; 104 // instead of: 105 // base::LazyInstance<T, base::internal::LeakyLazyInstanceTraits<T> > 106 // my_leaky_lazy_instance; 107 // (especially when T is MyLongTypeNameImplClientHolderFactory). 108 // Only use this internal::-qualified verbose form to extend this traits class 109 // (depending on its implementation details). 110 template <typename Type> 111 struct LeakyLazyInstanceTraits { 112 static const bool kRegisterOnExit = false; 113 #if DCHECK_IS_ON() 114 static const bool kAllowedToAccessOnNonjoinableThread = true; 115 #endif 116 NewLeakyLazyInstanceTraits117 static Type* New(void* instance) { 118 ANNOTATE_SCOPED_MEMORY_LEAK; 119 return LazyInstanceTraitsBase<Type>::New(instance); 120 } DeleteLeakyLazyInstanceTraits121 static void Delete(Type* instance) { 122 } 123 }; 124 125 template <typename Type> 126 struct ErrorMustSelectLazyOrDestructorAtExitForLazyInstance {}; 127 128 } // namespace internal 129 130 template < 131 typename Type, 132 typename Traits = 133 internal::ErrorMustSelectLazyOrDestructorAtExitForLazyInstance<Type>> 134 class LazyInstance { 135 public: 136 // Do not define a destructor, as doing so makes LazyInstance a 137 // non-POD-struct. We don't want that because then a static initializer will 138 // be created to register the (empty) destructor with atexit() under MSVC, for 139 // example. We handle destruction of the contained Type class explicitly via 140 // the OnExit member function, where needed. 141 // ~LazyInstance() {} 142 143 // Convenience typedef to avoid having to repeat Type for leaky lazy 144 // instances. 145 typedef LazyInstance<Type, internal::LeakyLazyInstanceTraits<Type>> Leaky; 146 typedef LazyInstance<Type, internal::DestructorAtExitLazyInstanceTraits<Type>> 147 DestructorAtExit; 148 Get()149 Type& Get() { 150 return *Pointer(); 151 } 152 Pointer()153 Type* Pointer() { 154 #if DCHECK_IS_ON() 155 if (!Traits::kAllowedToAccessOnNonjoinableThread) 156 internal::AssertSingletonAllowed(); 157 #endif 158 159 return subtle::GetOrCreateLazyPointer( 160 private_instance_, &Traits::New, private_buf_, 161 Traits::kRegisterOnExit ? OnExit : nullptr, this); 162 } 163 164 // Returns true if the lazy instance has been created. Unlike Get() and 165 // Pointer(), calling IsCreated() will not instantiate the object of Type. IsCreated()166 bool IsCreated() { 167 // Return true (i.e. "created") if |private_instance_| is either being 168 // created right now (i.e. |private_instance_| has value of 169 // internal::kLazyInstanceStateCreating) or was already created (i.e. 170 // |private_instance_| has any other non-zero value). 171 return 0 != private_instance_.load(std::memory_order_relaxed); 172 } 173 174 // MSVC gives a warning that the alignment expands the size of the 175 // LazyInstance struct to make the size a multiple of the alignment. This 176 // is expected in this case. 177 #if BUILDFLAG(IS_WIN) 178 #pragma warning(push) 179 #pragma warning(disable : 4324) 180 #endif 181 182 // Effectively private: member data is only public to allow the linker to 183 // statically initialize it and to maintain a POD class. DO NOT USE FROM 184 // OUTSIDE THIS CLASS. 185 std::atomic<uintptr_t> private_instance_; 186 187 // Preallocated space for the Type instance. 188 alignas(Type) char private_buf_[sizeof(Type)]; 189 190 #if BUILDFLAG(IS_WIN) 191 #pragma warning(pop) 192 #endif 193 194 private: instance()195 Type* instance() { 196 return reinterpret_cast<Type*>( 197 private_instance_.load(std::memory_order_relaxed)); 198 } 199 200 // Adapter function for use with AtExit. This should be called single 201 // threaded, so don't synchronize across threads. 202 // Calling OnExit while the instance is in use by other threads is a mistake. OnExit(void * lazy_instance)203 static void OnExit(void* lazy_instance) { 204 LazyInstance<Type, Traits>* me = 205 reinterpret_cast<LazyInstance<Type, Traits>*>(lazy_instance); 206 Traits::Delete(me->instance()); 207 me->private_instance_.store(0, std::memory_order_relaxed); 208 } 209 }; 210 211 } // namespace base 212 213 #endif // BASE_LAZY_INSTANCE_H_ 214