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 { |
64 | 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 | |
71 | 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 | |
91 | static Type* New(void* instance) { |
92 | return LazyInstanceTraitsBase<Type>::New(instance); |
93 | } |
94 | |
95 | 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 | |
115 | static Type* New(void* instance) { |
116 | ANNOTATE_SCOPED_MEMORY_LEAK; |
117 | return LazyInstanceTraitsBase<Type>::New(instance); |
118 | } |
119 | 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 | |
147 | Type& Get() { |
148 | return *Pointer(); |
149 | } |
150 | |
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. |
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: |
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. |
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 | |