| 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 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 // We pull out some of the functionality into non-templated functions, so we |
| 77 // can implement the more complicated pieces out of line in the .cc file. |
| 78 namespace internal { |
| 79 |
| 76 // Use LazyInstance<T>::Leaky for a less-verbose call-site typedef; e.g.: | 80 // Use LazyInstance<T>::Leaky for a less-verbose call-site typedef; e.g.: |
| 77 // base::LazyInstance<T>::Leaky my_leaky_lazy_instance; | 81 // base::LazyInstance<T>::Leaky my_leaky_lazy_instance; |
| 78 // instead of: | 82 // instead of: |
| 79 // base::LazyInstance<T, LeakyLazyInstanceTraits<T> > my_leaky_lazy_instance; | 83 // base::LazyInstance<T, base::internal::LeakyLazyInstanceTraits<T> > |
| 84 // my_leaky_lazy_instance; |
| 80 // (especially when T is MyLongTypeNameImplClientHolderFactory). | 85 // (especially when T is MyLongTypeNameImplClientHolderFactory). |
| 86 // Only use this internal::-qualified verbose form to extend this traits class |
| 87 // (depending on its implementation details). |
| 81 template <typename Type> | 88 template <typename Type> |
| 82 struct LeakyLazyInstanceTraits { | 89 struct LeakyLazyInstanceTraits { |
| 83 static const bool kRegisterOnExit = false; | 90 static const bool kRegisterOnExit = false; |
| 84 static const bool kAllowedToAccessOnNonjoinableThread = true; | 91 static const bool kAllowedToAccessOnNonjoinableThread = true; |
| 85 | 92 |
| 86 static Type* New(void* instance) { | 93 static Type* New(void* instance) { |
| 87 return DefaultLazyInstanceTraits<Type>::New(instance); | 94 return DefaultLazyInstanceTraits<Type>::New(instance); |
| 88 } | 95 } |
| 89 static void Delete(Type* instance) { | 96 static void Delete(Type* instance) { |
| 90 } | 97 } |
| 91 }; | 98 }; |
| 92 | 99 |
| 93 // We pull out some of the functionality into non-templated functions, so we | |
| 94 // can implement the more complicated pieces out of line in the .cc file. | |
| 95 namespace internal { | |
| 96 | |
| 97 // Our AtomicWord doubles as a spinlock, where a value of | 100 // Our AtomicWord doubles as a spinlock, where a value of |
| 98 // kBeingCreatedMarker means the spinlock is being held for creation. | 101 // kBeingCreatedMarker means the spinlock is being held for creation. |
| 99 static const subtle::AtomicWord kLazyInstanceStateCreating = 1; | 102 static const subtle::AtomicWord kLazyInstanceStateCreating = 1; |
| 100 | 103 |
| 101 // Check if instance needs to be created. If so return true otherwise | 104 // Check if instance needs to be created. If so return true otherwise |
| 102 // if another thread has beat us, wait for instance to be created and | 105 // if another thread has beat us, wait for instance to be created and |
| 103 // return false. | 106 // return false. |
| 104 BASE_EXPORT bool NeedsLazyInstance(subtle::AtomicWord* state); | 107 BASE_EXPORT bool NeedsLazyInstance(subtle::AtomicWord* state); |
| 105 | 108 |
| 106 // After creating an instance, call this to register the dtor to be called | 109 // After creating an instance, call this to register the dtor to be called |
| (...skipping 10 matching lines...) Expand all Loading... |
| 117 public: | 120 public: |
| 118 // Do not define a destructor, as doing so makes LazyInstance a | 121 // Do not define a destructor, as doing so makes LazyInstance a |
| 119 // non-POD-struct. We don't want that because then a static initializer will | 122 // non-POD-struct. We don't want that because then a static initializer will |
| 120 // be created to register the (empty) destructor with atexit() under MSVC, for | 123 // be created to register the (empty) destructor with atexit() under MSVC, for |
| 121 // example. We handle destruction of the contained Type class explicitly via | 124 // example. We handle destruction of the contained Type class explicitly via |
| 122 // the OnExit member function, where needed. | 125 // the OnExit member function, where needed. |
| 123 // ~LazyInstance() {} | 126 // ~LazyInstance() {} |
| 124 | 127 |
| 125 // Convenience typedef to avoid having to repeat Type for leaky lazy | 128 // Convenience typedef to avoid having to repeat Type for leaky lazy |
| 126 // instances. | 129 // instances. |
| 127 typedef LazyInstance<Type, LeakyLazyInstanceTraits<Type> > Leaky; | 130 typedef LazyInstance<Type, internal::LeakyLazyInstanceTraits<Type> > Leaky; |
| 128 | 131 |
| 129 Type& Get() { | 132 Type& Get() { |
| 130 return *Pointer(); | 133 return *Pointer(); |
| 131 } | 134 } |
| 132 | 135 |
| 133 Type* Pointer() { | 136 Type* Pointer() { |
| 134 #ifndef NDEBUG | 137 #ifndef NDEBUG |
| 135 // Avoid making TLS lookup on release builds. | 138 // Avoid making TLS lookup on release builds. |
| 136 if (!Traits::kAllowedToAccessOnNonjoinableThread) | 139 if (!Traits::kAllowedToAccessOnNonjoinableThread) |
| 137 ThreadRestrictions::AssertSingletonAllowed(); | 140 ThreadRestrictions::AssertSingletonAllowed(); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 198 LazyInstance<Type, Traits>* me = | 201 LazyInstance<Type, Traits>* me = |
| 199 reinterpret_cast<LazyInstance<Type, Traits>*>(lazy_instance); | 202 reinterpret_cast<LazyInstance<Type, Traits>*>(lazy_instance); |
| 200 Traits::Delete(me->instance()); | 203 Traits::Delete(me->instance()); |
| 201 subtle::Release_Store(&me->private_instance_, 0); | 204 subtle::Release_Store(&me->private_instance_, 0); |
| 202 } | 205 } |
| 203 }; | 206 }; |
| 204 | 207 |
| 205 } // namespace base | 208 } // namespace base |
| 206 | 209 |
| 207 #endif // BASE_LAZY_INSTANCE_H_ | 210 #endif // BASE_LAZY_INSTANCE_H_ |
| OLD | NEW |