1 // Copyright (c) 2008 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 base::LinkerInitialized constructor. 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(base::LINKER_INITIALIZED); 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 "base/atomicops.h" 39 #include "base/basictypes.h" 40 #include "base/dynamic_annotations.h" 41 42 namespace base { 43 44 template <typename Type> 45 struct DefaultLazyInstanceTraits { 46 static void New(void* instance) { 47 // Use placement new to initialize our instance in our preallocated space. 48 // The parenthesis is very important here to force POD type initialization. 49 new (instance) Type(); 50 } 51 static void Delete(void* instance) { 52 // Explicitly call the destructor. 53 reinterpret_cast<Type*>(instance)->~Type(); 54 } 55 }; 56 57 // We pull out some of the functionality into a non-templated base, so that we 58 // can implement the more complicated pieces out of line in the .cc file. 59 class LazyInstanceHelper { 60 protected: 61 enum { 62 STATE_EMPTY = 0, 63 STATE_CREATING = 1, 64 STATE_CREATED = 2 65 }; 66 67 explicit LazyInstanceHelper(LinkerInitialized x) { /* state_ is 0 */ } 68 // Declaring a destructor (even if it's empty) will cause MSVC to register a 69 // static initializer to register the empty destructor with atexit(). 70 71 // Make sure that instance is created, creating or waiting for it to be 72 // created if neccessary. Constructs with |ctor| in the space provided by 73 // |instance| and registers dtor for destruction at program exit. 74 void EnsureInstance(void* instance, void (*ctor)(void*), void (*dtor)(void*)); 75 76 base::subtle::Atomic32 state_; 77 78 private: 79 // Resets state of |helper| to STATE_EMPTY so that it can be reused. 80 // Not thread safe. 81 static void ResetState(void* helper); 82 83 DISALLOW_COPY_AND_ASSIGN(LazyInstanceHelper); 84 }; 85 86 template <typename Type, typename Traits = DefaultLazyInstanceTraits<Type> > 87 class LazyInstance : public LazyInstanceHelper { 88 public: 89 explicit LazyInstance(LinkerInitialized x) : LazyInstanceHelper(x) { } 90 // Declaring a destructor (even if it's empty) will cause MSVC to register a 91 // static initializer to register the empty destructor with atexit(). 92 93 Type& Get() { 94 return *Pointer(); 95 } 96 97 Type* Pointer() { 98 Type* instance = reinterpret_cast<Type*>(&buf_); 99 100 // We will hopefully have fast access when the instance is already created. 101 if (base::subtle::NoBarrier_Load(&state_) != STATE_CREATED) 102 EnsureInstance(instance, Traits::New, Traits::Delete); 103 104 // This annotation helps race detectors recognize correct lock-less 105 // synchronization between different threads calling Pointer(). 106 // We suggest dynamic race detection tool that 107 // "ctor(instance)" in EnsureInstance(...) happens before 108 // "return instance" in Pointer(). 109 // See the corresponding HAPPENS_BEFORE in EnsureInstance(...). 110 ANNOTATE_HAPPENS_AFTER(&state_); 111 112 return instance; 113 } 114 115 private: 116 int8 buf_[sizeof(Type)]; // Preallocate the space for the Type instance. 117 118 DISALLOW_COPY_AND_ASSIGN(LazyInstance); 119 }; 120 121 } // namespace base 122 123 #endif // BASE_LAZY_INSTANCE_H_ 124