OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 // The LazyInstance<Type, Traits> class manages a single instance of Type, | 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 | 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 | 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 | 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() | 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. | 10 // and Pointer() will always return the same, completely initialized instance. |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
66 // Use placement new to initialize our instance in our preallocated space. | 66 // Use placement new to initialize our instance in our preallocated space. |
67 // The parenthesis is very important here to force POD type initialization. | 67 // The parenthesis is very important here to force POD type initialization. |
68 return new (instance) Type(); | 68 return new (instance) Type(); |
69 } | 69 } |
70 static void Delete(Type* instance) { | 70 static void Delete(Type* instance) { |
71 // Explicitly call the destructor. | 71 // Explicitly call the destructor. |
72 instance->~Type(); | 72 instance->~Type(); |
73 } | 73 } |
74 }; | 74 }; |
75 | 75 |
| 76 // Use LazyInstance<T>::Leaky for a less-verbose call-site typedef; e.g.: |
| 77 // base::LazyInstance<T>::Leaky my_leaky_lazy_instance; |
| 78 // instead of: |
| 79 // base::LazyInstance<T, LeakyLazyInstanceTraits<T> > my_leaky_lazy_instance; |
| 80 // (especially when T is MyLongTypeNameImplClientHolderFactory). |
76 template <typename Type> | 81 template <typename Type> |
77 struct LeakyLazyInstanceTraits { | 82 struct LeakyLazyInstanceTraits { |
78 static const bool kRegisterOnExit = false; | 83 static const bool kRegisterOnExit = false; |
79 static const bool kAllowedToAccessOnNonjoinableThread = true; | 84 static const bool kAllowedToAccessOnNonjoinableThread = true; |
80 | 85 |
81 static Type* New(void* instance) { | 86 static Type* New(void* instance) { |
82 return DefaultLazyInstanceTraits<Type>::New(instance); | 87 return DefaultLazyInstanceTraits<Type>::New(instance); |
83 } | 88 } |
84 static void Delete(Type* instance) { | 89 static void Delete(Type* instance) { |
85 } | 90 } |
(...skipping 24 matching lines...) Expand all Loading... |
110 template <typename Type, typename Traits = DefaultLazyInstanceTraits<Type> > | 115 template <typename Type, typename Traits = DefaultLazyInstanceTraits<Type> > |
111 class LazyInstance { | 116 class LazyInstance { |
112 public: | 117 public: |
113 // Do not define a destructor, as doing so makes LazyInstance a | 118 // Do not define a destructor, as doing so makes LazyInstance a |
114 // non-POD-struct. We don't want that because then a static initializer will | 119 // non-POD-struct. We don't want that because then a static initializer will |
115 // be created to register the (empty) destructor with atexit() under MSVC, for | 120 // be created to register the (empty) destructor with atexit() under MSVC, for |
116 // example. We handle destruction of the contained Type class explicitly via | 121 // example. We handle destruction of the contained Type class explicitly via |
117 // the OnExit member function, where needed. | 122 // the OnExit member function, where needed. |
118 // ~LazyInstance() {} | 123 // ~LazyInstance() {} |
119 | 124 |
| 125 // Convenience typedef to avoid having to repeat Type for leaky lazy |
| 126 // instances. |
| 127 typedef LazyInstance<Type, LeakyLazyInstanceTraits<Type> > Leaky; |
| 128 |
120 Type& Get() { | 129 Type& Get() { |
121 return *Pointer(); | 130 return *Pointer(); |
122 } | 131 } |
123 | 132 |
124 Type* Pointer() { | 133 Type* Pointer() { |
125 #ifndef NDEBUG | 134 #ifndef NDEBUG |
126 // Avoid making TLS lookup on release builds. | 135 // Avoid making TLS lookup on release builds. |
127 if (!Traits::kAllowedToAccessOnNonjoinableThread) | 136 if (!Traits::kAllowedToAccessOnNonjoinableThread) |
128 ThreadRestrictions::AssertSingletonAllowed(); | 137 ThreadRestrictions::AssertSingletonAllowed(); |
129 #endif | 138 #endif |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
189 LazyInstance<Type, Traits>* me = | 198 LazyInstance<Type, Traits>* me = |
190 reinterpret_cast<LazyInstance<Type, Traits>*>(lazy_instance); | 199 reinterpret_cast<LazyInstance<Type, Traits>*>(lazy_instance); |
191 Traits::Delete(me->instance()); | 200 Traits::Delete(me->instance()); |
192 subtle::Release_Store(&me->private_instance_, 0); | 201 subtle::Release_Store(&me->private_instance_, 0); |
193 } | 202 } |
194 }; | 203 }; |
195 | 204 |
196 } // namespace base | 205 } // namespace base |
197 | 206 |
198 #endif // BASE_LAZY_INSTANCE_H_ | 207 #endif // BASE_LAZY_INSTANCE_H_ |
OLD | NEW |