| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 50 // initialization, as base's LINKER_INITIALIZED requires a constructor and on | 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 | 51 // some compilers (notably gcc 4.4) this still ends up needing runtime |
| 52 // initialization. | 52 // initialization. |
| 53 #define LAZY_INSTANCE_INITIALIZER {0} | 53 #define LAZY_INSTANCE_INITIALIZER {0} |
| 54 | 54 |
| 55 namespace base { | 55 namespace base { |
| 56 | 56 |
| 57 template <typename Type> | 57 template <typename Type> |
| 58 struct DefaultLazyInstanceTraits { | 58 struct DefaultLazyInstanceTraits { |
| 59 static const bool kRegisterOnExit = true; | 59 static const bool kRegisterOnExit = true; |
| 60 #ifndef NDEBUG |
| 60 static const bool kAllowedToAccessOnNonjoinableThread = false; | 61 static const bool kAllowedToAccessOnNonjoinableThread = false; |
| 62 #endif |
| 61 | 63 |
| 62 static Type* New(void* instance) { | 64 static Type* New(void* instance) { |
| 63 DCHECK_EQ(reinterpret_cast<uintptr_t>(instance) & (ALIGNOF(Type) - 1), 0u) | 65 DCHECK_EQ(reinterpret_cast<uintptr_t>(instance) & (ALIGNOF(Type) - 1), 0u) |
| 64 << ": Bad boy, the buffer passed to placement new is not aligned!\n" | 66 << ": Bad boy, the buffer passed to placement new is not aligned!\n" |
| 65 "This may break some stuff like SSE-based optimizations assuming the " | 67 "This may break some stuff like SSE-based optimizations assuming the " |
| 66 "<Type> objects are word aligned."; | 68 "<Type> objects are word aligned."; |
| 67 // Use placement new to initialize our instance in our preallocated space. | 69 // Use placement new to initialize our instance in our preallocated space. |
| 68 // The parenthesis is very important here to force POD type initialization. | 70 // The parenthesis is very important here to force POD type initialization. |
| 69 return new (instance) Type(); | 71 return new (instance) Type(); |
| 70 } | 72 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 82 // base::LazyInstance<T>::Leaky my_leaky_lazy_instance; | 84 // base::LazyInstance<T>::Leaky my_leaky_lazy_instance; |
| 83 // instead of: | 85 // instead of: |
| 84 // base::LazyInstance<T, base::internal::LeakyLazyInstanceTraits<T> > | 86 // base::LazyInstance<T, base::internal::LeakyLazyInstanceTraits<T> > |
| 85 // my_leaky_lazy_instance; | 87 // my_leaky_lazy_instance; |
| 86 // (especially when T is MyLongTypeNameImplClientHolderFactory). | 88 // (especially when T is MyLongTypeNameImplClientHolderFactory). |
| 87 // Only use this internal::-qualified verbose form to extend this traits class | 89 // Only use this internal::-qualified verbose form to extend this traits class |
| 88 // (depending on its implementation details). | 90 // (depending on its implementation details). |
| 89 template <typename Type> | 91 template <typename Type> |
| 90 struct LeakyLazyInstanceTraits { | 92 struct LeakyLazyInstanceTraits { |
| 91 static const bool kRegisterOnExit = false; | 93 static const bool kRegisterOnExit = false; |
| 94 #ifndef NDEBUG |
| 92 static const bool kAllowedToAccessOnNonjoinableThread = true; | 95 static const bool kAllowedToAccessOnNonjoinableThread = true; |
| 96 #endif |
| 93 | 97 |
| 94 static Type* New(void* instance) { | 98 static Type* New(void* instance) { |
| 95 ANNOTATE_SCOPED_MEMORY_LEAK; | 99 ANNOTATE_SCOPED_MEMORY_LEAK; |
| 96 return DefaultLazyInstanceTraits<Type>::New(instance); | 100 return DefaultLazyInstanceTraits<Type>::New(instance); |
| 97 } | 101 } |
| 98 static void Delete(Type* instance) { | 102 static void Delete(Type* instance) { |
| 99 } | 103 } |
| 100 }; | 104 }; |
| 101 | 105 |
| 102 // Our AtomicWord doubles as a spinlock, where a value of | 106 // Our AtomicWord doubles as a spinlock, where a value of |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 203 LazyInstance<Type, Traits>* me = | 207 LazyInstance<Type, Traits>* me = |
| 204 reinterpret_cast<LazyInstance<Type, Traits>*>(lazy_instance); | 208 reinterpret_cast<LazyInstance<Type, Traits>*>(lazy_instance); |
| 205 Traits::Delete(me->instance()); | 209 Traits::Delete(me->instance()); |
| 206 subtle::NoBarrier_Store(&me->private_instance_, 0); | 210 subtle::NoBarrier_Store(&me->private_instance_, 0); |
| 207 } | 211 } |
| 208 }; | 212 }; |
| 209 | 213 |
| 210 } // namespace base | 214 } // namespace base |
| 211 | 215 |
| 212 #endif // BASE_LAZY_INSTANCE_H_ | 216 #endif // BASE_LAZY_INSTANCE_H_ |
| OLD | NEW |