Index: base/lazy_instance.h |
diff --git a/base/lazy_instance.h b/base/lazy_instance.h |
index 1183806bef5565ed9a142b1c26cc94e68de0ded0..070e436d1f0c5a74534ba8fb1a8535a29db789e0 100644 |
--- a/base/lazy_instance.h |
+++ b/base/lazy_instance.h |
@@ -24,11 +24,11 @@ |
// requires that Type be a complete type so we can determine the size. |
// |
// Example usage: |
-// static LazyInstance<MyClass> my_instance = LAZY_INSTANCE_INITIALIZER; |
+// static LazyInstance<MyClass>::Leaky inst = LAZY_INSTANCE_INITIALIZER; |
// void SomeMethod() { |
-// my_instance.Get().SomeMethod(); // MyClass::SomeMethod() |
+// inst.Get().SomeMethod(); // MyClass::SomeMethod() |
// |
-// MyClass* ptr = my_instance.Pointer(); |
+// MyClass* ptr = inst.Pointer(); |
// ptr->DoDoDo(); // MyClass::DoDoDo |
// } |
@@ -53,22 +53,15 @@ |
namespace base { |
template <typename Type> |
-struct DefaultLazyInstanceTraits { |
- static const bool kRegisterOnExit = true; |
-#if DCHECK_IS_ON() |
- static const bool kAllowedToAccessOnNonjoinableThread = false; |
-#endif |
- |
+struct LazyInstanceTraitsBase { |
static Type* New(void* instance) { |
- DCHECK_EQ(reinterpret_cast<uintptr_t>(instance) & (ALIGNOF(Type) - 1), 0u) |
- << ": Bad boy, the buffer passed to placement new is not aligned!\n" |
- "This may break some stuff like SSE-based optimizations assuming the " |
- "<Type> objects are word aligned."; |
+ DCHECK_EQ(reinterpret_cast<uintptr_t>(instance) & (ALIGNOF(Type) - 1), 0u); |
// Use placement new to initialize our instance in our preallocated space. |
// The parenthesis is very important here to force POD type initialization. |
return new (instance) Type(); |
} |
- static void Delete(Type* instance) { |
+ |
+ static void CallDestructor(Type* instance) { |
// Explicitly call the destructor. |
instance->~Type(); |
} |
@@ -78,6 +71,25 @@ struct DefaultLazyInstanceTraits { |
// can implement the more complicated pieces out of line in the .cc file. |
namespace internal { |
+// This traits class causes destruction the contained Type at process exit via |
+// AtExitManager. This is probably generally not what you want. Instead, prefer |
+// Leaky below. |
+template <typename Type> |
+struct DestructorAtExitLazyInstanceTraits { |
+ static const bool kRegisterOnExit = true; |
+#if DCHECK_IS_ON() |
+ static const bool kAllowedToAccessOnNonjoinableThread = false; |
+#endif |
+ |
+ static Type* New(void* instance) { |
+ return LazyInstanceTraitsBase<Type>::New(instance); |
+ } |
+ |
+ static void Delete(Type* instance) { |
+ LazyInstanceTraitsBase<Type>::CallDestructor(instance); |
+ } |
+}; |
+ |
// Use LazyInstance<T>::Leaky for a less-verbose call-site typedef; e.g.: |
// base::LazyInstance<T>::Leaky my_leaky_lazy_instance; |
// instead of: |
@@ -95,12 +107,15 @@ struct LeakyLazyInstanceTraits { |
static Type* New(void* instance) { |
ANNOTATE_SCOPED_MEMORY_LEAK; |
- return DefaultLazyInstanceTraits<Type>::New(instance); |
+ return LazyInstanceTraitsBase<Type>::New(instance); |
} |
static void Delete(Type* instance) { |
} |
}; |
+template <typename Type> |
+struct ErrorMustSelectLazyOrDestructorAtExitForLazyInstance {}; |
+ |
// Our AtomicWord doubles as a spinlock, where a value of |
// kLazyInstanceStateCreating means the spinlock is being held for creation. |
static const subtle::AtomicWord kLazyInstanceStateCreating = 1; |
@@ -119,7 +134,10 @@ BASE_EXPORT void CompleteLazyInstance(subtle::AtomicWord* state, |
} // namespace internal |
-template <typename Type, typename Traits = DefaultLazyInstanceTraits<Type> > |
+template < |
+ typename Type, |
+ typename Traits = |
+ internal::ErrorMustSelectLazyOrDestructorAtExitForLazyInstance<Type>> |
class LazyInstance { |
public: |
// Do not define a destructor, as doing so makes LazyInstance a |
@@ -131,7 +149,9 @@ class LazyInstance { |
// Convenience typedef to avoid having to repeat Type for leaky lazy |
// instances. |
- typedef LazyInstance<Type, internal::LeakyLazyInstanceTraits<Type> > Leaky; |
+ typedef LazyInstance<Type, internal::LeakyLazyInstanceTraits<Type>> Leaky; |
+ typedef LazyInstance<Type, internal::DestructorAtExitLazyInstanceTraits<Type>> |
+ DestructorAtExit; |
Type& Get() { |
return *Pointer(); |