|
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 // The LazyInstance<Type, Traits> class manages a single instance of Type, |
|
6 // which will be lazily created on the first time it's accessed. This class is |
|
7 // useful for places you would normally use a function-level static, but you |
|
8 // need to have guaranteed thread-safety. The Type constructor will only ever |
|
9 // be called once, even if two threads are racing to create the object. Get() |
|
10 // and Pointer() will always return the same, completely initialized instance. |
|
11 // When the instance is constructed it is registered with AtExitManager. The |
|
12 // destructor will be called on program exit. |
|
13 // |
|
14 // LazyInstance is completely thread safe, assuming that you create it safely. |
|
15 // The class was designed to be POD initialized, so it shouldn't require a |
|
16 // static constructor. It really only makes sense to declare a LazyInstance as |
|
17 // a global variable using the LAZY_INSTANCE_INITIALIZER initializer. |
|
18 // |
|
19 // LazyInstance is similar to Singleton, except it does not have the singleton |
|
20 // property. You can have multiple LazyInstance's of the same type, and each |
|
21 // will manage a unique instance. It also preallocates the space for Type, as |
|
22 // to avoid allocating the Type instance on the heap. This may help with the |
|
23 // performance of creating the instance, and reducing heap fragmentation. This |
|
24 // requires that Type be a complete type so we can determine the size. |
|
25 // |
|
26 // Example usage: |
|
27 // static LazyInstance<MyClass> my_instance = LAZY_INSTANCE_INITIALIZER; |
|
28 // void SomeMethod() { |
|
29 // my_instance.Get().SomeMethod(); // MyClass::SomeMethod() |
|
30 // |
|
31 // MyClass* ptr = my_instance.Pointer(); |
|
32 // ptr->DoDoDo(); // MyClass::DoDoDo |
|
33 // } |
|
34 |
|
35 #ifndef BASE_LAZY_INSTANCE_H_ |
|
36 #define BASE_LAZY_INSTANCE_H_ |
|
37 |
|
38 #include <new> // For placement new. |
|
39 |
|
40 #include "base/atomicops.h" |
|
41 #include "base/base_export.h" |
|
42 #include "base/basictypes.h" |
|
43 #include "base/debug/leak_annotations.h" |
|
44 #include "base/logging.h" |
|
45 #include "base/memory/aligned_memory.h" |
|
46 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" |
|
47 #include "base/threading/thread_restrictions.h" |
|
48 |
|
49 // LazyInstance uses its own struct initializer-list style static |
|
50 // initialization, as base's LINKER_INITIALIZED requires a constructor and on |
|
51 // some compilers (notably gcc 4.4) this still ends up needing runtime |
|
52 // initialization. |
|
53 #define LAZY_INSTANCE_INITIALIZER {0} |
|
54 |
|
55 namespace base { |
|
56 |
|
57 template <typename Type> |
|
58 struct DefaultLazyInstanceTraits { |
|
59 static const bool kRegisterOnExit = true; |
|
60 static const bool kAllowedToAccessOnNonjoinableThread = false; |
|
61 |
|
62 static Type* New(void* instance) { |
|
63 DCHECK_EQ(reinterpret_cast<uintptr_t>(instance) & (ALIGNOF(Type) - 1), 0u) |
|
64 << ": Bad boy, the buffer passed to placement new is not aligned!\n" |
|
65 "This may break some stuff like SSE-based optimizations assuming the " |
|
66 "<Type> objects are word aligned."; |
|
67 // Use placement new to initialize our instance in our preallocated space. |
|
68 // The parenthesis is very important here to force POD type initialization. |
|
69 return new (instance) Type(); |
|
70 } |
|
71 static void Delete(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 // Use LazyInstance<T>::Leaky for a less-verbose call-site typedef; e.g.: |
|
82 // base::LazyInstance<T>::Leaky my_leaky_lazy_instance; |
|
83 // instead of: |
|
84 // base::LazyInstance<T, base::internal::LeakyLazyInstanceTraits<T> > |
|
85 // my_leaky_lazy_instance; |
|
86 // (especially when T is MyLongTypeNameImplClientHolderFactory). |
|
87 // Only use this internal::-qualified verbose form to extend this traits class |
|
88 // (depending on its implementation details). |
|
89 template <typename Type> |
|
90 struct LeakyLazyInstanceTraits { |
|
91 static const bool kRegisterOnExit = false; |
|
92 static const bool kAllowedToAccessOnNonjoinableThread = true; |
|
93 |
|
94 static Type* New(void* instance) { |
|
95 ANNOTATE_SCOPED_MEMORY_LEAK; |
|
96 return DefaultLazyInstanceTraits<Type>::New(instance); |
|
97 } |
|
98 static void Delete(Type* instance) { |
|
99 } |
|
100 }; |
|
101 |
|
102 // Our AtomicWord doubles as a spinlock, where a value of |
|
103 // kBeingCreatedMarker means the spinlock is being held for creation. |
|
104 static const subtle::AtomicWord kLazyInstanceStateCreating = 1; |
|
105 |
|
106 // Check if instance needs to be created. If so return true otherwise |
|
107 // if another thread has beat us, wait for instance to be created and |
|
108 // return false. |
|
109 BASE_EXPORT bool NeedsLazyInstance(subtle::AtomicWord* state); |
|
110 |
|
111 // After creating an instance, call this to register the dtor to be called |
|
112 // at program exit and to update the atomic state to hold the |new_instance| |
|
113 BASE_EXPORT void CompleteLazyInstance(subtle::AtomicWord* state, |
|
114 subtle::AtomicWord new_instance, |
|
115 void* lazy_instance, |
|
116 void (*dtor)(void*)); |
|
117 |
|
118 } // namespace internal |
|
119 |
|
120 template <typename Type, typename Traits = DefaultLazyInstanceTraits<Type> > |
|
121 class LazyInstance { |
|
122 public: |
|
123 // Do not define a destructor, as doing so makes LazyInstance a |
|
124 // non-POD-struct. We don't want that because then a static initializer will |
|
125 // be created to register the (empty) destructor with atexit() under MSVC, for |
|
126 // example. We handle destruction of the contained Type class explicitly via |
|
127 // the OnExit member function, where needed. |
|
128 // ~LazyInstance() {} |
|
129 |
|
130 // Convenience typedef to avoid having to repeat Type for leaky lazy |
|
131 // instances. |
|
132 typedef LazyInstance<Type, internal::LeakyLazyInstanceTraits<Type> > Leaky; |
|
133 |
|
134 Type& Get() { |
|
135 return *Pointer(); |
|
136 } |
|
137 |
|
138 Type* Pointer() { |
|
139 #ifndef NDEBUG |
|
140 // Avoid making TLS lookup on release builds. |
|
141 if (!Traits::kAllowedToAccessOnNonjoinableThread) |
|
142 ThreadRestrictions::AssertSingletonAllowed(); |
|
143 #endif |
|
144 // If any bit in the created mask is true, the instance has already been |
|
145 // fully constructed. |
|
146 static const subtle::AtomicWord kLazyInstanceCreatedMask = |
|
147 ~internal::kLazyInstanceStateCreating; |
|
148 |
|
149 // We will hopefully have fast access when the instance is already created. |
|
150 // Since a thread sees private_instance_ == 0 or kLazyInstanceStateCreating |
|
151 // at most once, the load is taken out of NeedsInstance() as a fast-path. |
|
152 // The load has acquire memory ordering as a thread which sees |
|
153 // private_instance_ > creating needs to acquire visibility over |
|
154 // the associated data (private_buf_). Pairing Release_Store is in |
|
155 // CompleteLazyInstance(). |
|
156 subtle::AtomicWord value = subtle::Acquire_Load(&private_instance_); |
|
157 if (!(value & kLazyInstanceCreatedMask) && |
|
158 internal::NeedsLazyInstance(&private_instance_)) { |
|
159 // Create the instance in the space provided by |private_buf_|. |
|
160 value = reinterpret_cast<subtle::AtomicWord>( |
|
161 Traits::New(private_buf_.void_data())); |
|
162 internal::CompleteLazyInstance(&private_instance_, value, this, |
|
163 Traits::kRegisterOnExit ? OnExit : NULL); |
|
164 } |
|
165 |
|
166 // This annotation helps race detectors recognize correct lock-less |
|
167 // synchronization between different threads calling Pointer(). |
|
168 // We suggest dynamic race detection tool that "Traits::New" above |
|
169 // and CompleteLazyInstance(...) happens before "return instance()" below. |
|
170 // See the corresponding HAPPENS_BEFORE in CompleteLazyInstance(...). |
|
171 ANNOTATE_HAPPENS_AFTER(&private_instance_); |
|
172 return instance(); |
|
173 } |
|
174 |
|
175 bool operator==(Type* p) { |
|
176 switch (subtle::NoBarrier_Load(&private_instance_)) { |
|
177 case 0: |
|
178 return p == NULL; |
|
179 case internal::kLazyInstanceStateCreating: |
|
180 return static_cast<void*>(p) == private_buf_.void_data(); |
|
181 default: |
|
182 return p == instance(); |
|
183 } |
|
184 } |
|
185 |
|
186 // Effectively private: member data is only public to allow the linker to |
|
187 // statically initialize it and to maintain a POD class. DO NOT USE FROM |
|
188 // OUTSIDE THIS CLASS. |
|
189 |
|
190 subtle::AtomicWord private_instance_; |
|
191 // Preallocated space for the Type instance. |
|
192 base::AlignedMemory<sizeof(Type), ALIGNOF(Type)> private_buf_; |
|
193 |
|
194 private: |
|
195 Type* instance() { |
|
196 return reinterpret_cast<Type*>(subtle::NoBarrier_Load(&private_instance_)); |
|
197 } |
|
198 |
|
199 // Adapter function for use with AtExit. This should be called single |
|
200 // threaded, so don't synchronize across threads. |
|
201 // Calling OnExit while the instance is in use by other threads is a mistake. |
|
202 static void OnExit(void* lazy_instance) { |
|
203 LazyInstance<Type, Traits>* me = |
|
204 reinterpret_cast<LazyInstance<Type, Traits>*>(lazy_instance); |
|
205 Traits::Delete(me->instance()); |
|
206 subtle::NoBarrier_Store(&me->private_instance_, 0); |
|
207 } |
|
208 }; |
|
209 |
|
210 } // namespace base |
|
211 |
|
212 #endif // BASE_LAZY_INSTANCE_H_ |