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 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 <new> // For placement new. 49 50 #include "base/atomicops.h" 51 #include "base/debug/leak_annotations.h" 52 #include "base/lazy_instance_helpers.h" 53 #include "base/logging.h" 54 #include "base/threading/thread_restrictions.h" 55 56 // LazyInstance uses its own struct initializer-list style static 57 // initialization, which does not require a constructor. 58 #define LAZY_INSTANCE_INITIALIZER {} 59 60 namespace base { 61 62 template <typename Type> 63 struct LazyInstanceTraitsBase { NewLazyInstanceTraitsBase64 static Type* New(void* instance) { 65 DCHECK_EQ(reinterpret_cast<uintptr_t>(instance) & (alignof(Type) - 1), 0u); 66 // Use placement new to initialize our instance in our preallocated space. 67 // The parenthesis is very important here to force POD type initialization. 68 return new (instance) Type(); 69 } 70 CallDestructorLazyInstanceTraitsBase71 static void CallDestructor(Type* instance) { 72 // Explicitly call the destructor. 73 instance->~Type(); 74 } 75 }; 76 77 // We pull out some of the functionality into non-templated functions, so we 78 // can implement the more complicated pieces out of line in the .cc file. 79 namespace internal { 80 81 // This traits class causes destruction the contained Type at process exit via 82 // AtExitManager. This is probably generally not what you want. Instead, prefer 83 // Leaky below. 84 template <typename Type> 85 struct DestructorAtExitLazyInstanceTraits { 86 static const bool kRegisterOnExit = true; 87 #if DCHECK_IS_ON() 88 static const bool kAllowedToAccessOnNonjoinableThread = false; 89 #endif 90 NewDestructorAtExitLazyInstanceTraits91 static Type* New(void* instance) { 92 return LazyInstanceTraitsBase<Type>::New(instance); 93 } 94 DeleteDestructorAtExitLazyInstanceTraits95 static void Delete(Type* instance) { 96 LazyInstanceTraitsBase<Type>::CallDestructor(instance); 97 } 98 }; 99 100 // Use LazyInstance<T>::Leaky for a less-verbose call-site typedef; e.g.: 101 // base::LazyInstance<T>::Leaky my_leaky_lazy_instance; 102 // instead of: 103 // base::LazyInstance<T, base::internal::LeakyLazyInstanceTraits<T> > 104 // my_leaky_lazy_instance; 105 // (especially when T is MyLongTypeNameImplClientHolderFactory). 106 // Only use this internal::-qualified verbose form to extend this traits class 107 // (depending on its implementation details). 108 template <typename Type> 109 struct LeakyLazyInstanceTraits { 110 static const bool kRegisterOnExit = false; 111 #if DCHECK_IS_ON() 112 static const bool kAllowedToAccessOnNonjoinableThread = true; 113 #endif 114 NewLeakyLazyInstanceTraits115 static Type* New(void* instance) { 116 ANNOTATE_SCOPED_MEMORY_LEAK; 117 return LazyInstanceTraitsBase<Type>::New(instance); 118 } DeleteLeakyLazyInstanceTraits119 static void Delete(Type* instance) { 120 } 121 }; 122 123 template <typename Type> 124 struct ErrorMustSelectLazyOrDestructorAtExitForLazyInstance {}; 125 126 } // namespace internal 127 128 template < 129 typename Type, 130 typename Traits = 131 internal::ErrorMustSelectLazyOrDestructorAtExitForLazyInstance<Type>> 132 class LazyInstance { 133 public: 134 // Do not define a destructor, as doing so makes LazyInstance a 135 // non-POD-struct. We don't want that because then a static initializer will 136 // be created to register the (empty) destructor with atexit() under MSVC, for 137 // example. We handle destruction of the contained Type class explicitly via 138 // the OnExit member function, where needed. 139 // ~LazyInstance() {} 140 141 // Convenience typedef to avoid having to repeat Type for leaky lazy 142 // instances. 143 typedef LazyInstance<Type, internal::LeakyLazyInstanceTraits<Type>> Leaky; 144 typedef LazyInstance<Type, internal::DestructorAtExitLazyInstanceTraits<Type>> 145 DestructorAtExit; 146 Get()147 Type& Get() { 148 return *Pointer(); 149 } 150 Pointer()151 Type* Pointer() { 152 #if DCHECK_IS_ON() 153 if (!Traits::kAllowedToAccessOnNonjoinableThread) 154 ThreadRestrictions::AssertSingletonAllowed(); 155 #endif 156 157 return subtle::GetOrCreateLazyPointer( 158 &private_instance_, &Traits::New, private_buf_, 159 Traits::kRegisterOnExit ? OnExit : nullptr, this); 160 } 161 162 // Returns true if the lazy instance has been created. Unlike Get() and 163 // Pointer(), calling IsCreated() will not instantiate the object of Type. IsCreated()164 bool IsCreated() { 165 // Return true (i.e. "created") if |private_instance_| is either being 166 // created right now (i.e. |private_instance_| has value of 167 // internal::kLazyInstanceStateCreating) or was already created (i.e. 168 // |private_instance_| has any other non-zero value). 169 return 0 != subtle::NoBarrier_Load(&private_instance_); 170 } 171 172 // MSVC gives a warning that the alignment expands the size of the 173 // LazyInstance struct to make the size a multiple of the alignment. This 174 // is expected in this case. 175 #if defined(OS_WIN) 176 #pragma warning(push) 177 #pragma warning(disable: 4324) 178 #endif 179 180 // Effectively private: member data is only public to allow the linker to 181 // statically initialize it and to maintain a POD class. DO NOT USE FROM 182 // OUTSIDE THIS CLASS. 183 subtle::AtomicWord private_instance_; 184 185 // Preallocated space for the Type instance. 186 alignas(Type) char private_buf_[sizeof(Type)]; 187 188 #if defined(OS_WIN) 189 #pragma warning(pop) 190 #endif 191 192 private: instance()193 Type* instance() { 194 return reinterpret_cast<Type*>(subtle::NoBarrier_Load(&private_instance_)); 195 } 196 197 // Adapter function for use with AtExit. This should be called single 198 // threaded, so don't synchronize across threads. 199 // Calling OnExit while the instance is in use by other threads is a mistake. OnExit(void * lazy_instance)200 static void OnExit(void* lazy_instance) { 201 LazyInstance<Type, Traits>* me = 202 reinterpret_cast<LazyInstance<Type, Traits>*>(lazy_instance); 203 Traits::Delete(me->instance()); 204 subtle::NoBarrier_Store(&me->private_instance_, 0); 205 } 206 }; 207 208 } // namespace base 209 210 #endif // BASE_LAZY_INSTANCE_H_ 211