michael@0: // Copyright (c) 2008 The Chromium Authors. All rights reserved. michael@0: // Use of this source code is governed by a BSD-style license that can be michael@0: // found in the LICENSE file. michael@0: michael@0: // The LazyInstance class manages a single instance of Type, michael@0: // which will be lazily created on the first time it's accessed. This class is michael@0: // useful for places you would normally use a function-level static, but you michael@0: // need to have guaranteed thread-safety. The Type constructor will only ever michael@0: // be called once, even if two threads are racing to create the object. Get() michael@0: // and Pointer() will always return the same, completely initialized instance. michael@0: // When the instance is constructed it is registered with AtExitManager. The michael@0: // destructor will be called on program exit. michael@0: // michael@0: // LazyInstance is completely thread safe, assuming that you create it safely. michael@0: // The class was designed to be POD initialized, so it shouldn't require a michael@0: // static constructor. It really only makes sense to declare a LazyInstance as michael@0: // a global variable using the base::LinkerInitialized constructor. michael@0: // michael@0: // LazyInstance is similar to Singleton, except it does not have the singleton michael@0: // property. You can have multiple LazyInstance's of the same type, and each michael@0: // will manage a unique instance. It also preallocates the space for Type, as michael@0: // to avoid allocating the Type instance on the heap. This may help with the michael@0: // performance of creating the instance, and reducing heap fragmentation. This michael@0: // requires that Type be a complete type so we can determine the size. michael@0: // michael@0: // Example usage: michael@0: // static LazyInstance my_instance(base::LINKER_INITIALIZED); michael@0: // void SomeMethod() { michael@0: // my_instance.Get().SomeMethod(); // MyClass::SomeMethod() michael@0: // michael@0: // MyClass* ptr = my_instance.Pointer(); michael@0: // ptr->DoDoDo(); // MyClass::DoDoDo michael@0: // } michael@0: michael@0: #ifndef BASE_LAZY_INSTANCE_H_ michael@0: #define BASE_LAZY_INSTANCE_H_ michael@0: michael@0: #include "base/atomicops.h" michael@0: #include "base/basictypes.h" michael@0: michael@0: namespace base { michael@0: michael@0: template michael@0: struct DefaultLazyInstanceTraits { michael@0: static void New(void* instance) { michael@0: // Use placement new to initialize our instance in our preallocated space. michael@0: // The parenthesis is very important here to force POD type initialization. michael@0: new (instance) Type(); michael@0: } michael@0: static void Delete(void* instance) { michael@0: // Explicitly call the destructor. michael@0: reinterpret_cast(instance)->~Type(); michael@0: } michael@0: }; michael@0: michael@0: // We pull out some of the functionality into a non-templated base, so that we michael@0: // can implement the more complicated pieces out of line in the .cc file. michael@0: class LazyInstanceHelper { michael@0: protected: michael@0: enum { michael@0: STATE_EMPTY = 0, michael@0: STATE_CREATING = 1, michael@0: STATE_CREATED = 2 michael@0: }; michael@0: michael@0: explicit LazyInstanceHelper(LinkerInitialized x) { /* state_ is 0 */ } michael@0: // Declaring a destructor (even if it's empty) will cause MSVC to register a michael@0: // static initializer to register the empty destructor with atexit(). michael@0: michael@0: // Make sure that instance is created, creating or waiting for it to be michael@0: // created if neccessary. Constructs with |ctor| in the space provided by michael@0: // |instance| and registers dtor for destruction at program exit. michael@0: void EnsureInstance(void* instance, void (*ctor)(void*), void (*dtor)(void*)); michael@0: michael@0: base::subtle::Atomic32 state_; michael@0: michael@0: private: michael@0: DISALLOW_COPY_AND_ASSIGN(LazyInstanceHelper); michael@0: }; michael@0: michael@0: template > michael@0: class LazyInstance : public LazyInstanceHelper { michael@0: public: michael@0: explicit LazyInstance(LinkerInitialized x) : LazyInstanceHelper(x) { } michael@0: // Declaring a destructor (even if it's empty) will cause MSVC to register a michael@0: // static initializer to register the empty destructor with atexit(). michael@0: michael@0: Type& Get() { michael@0: return *Pointer(); michael@0: } michael@0: michael@0: Type* Pointer() { michael@0: Type* instance = reinterpret_cast(&buf_); michael@0: michael@0: // We will hopefully have fast access when the instance is already created. michael@0: if (base::subtle::NoBarrier_Load(&state_) != STATE_CREATED) michael@0: EnsureInstance(instance, Traits::New, Traits::Delete); michael@0: michael@0: return instance; michael@0: } michael@0: michael@0: private: michael@0: int8_t buf_[sizeof(Type)]; // Preallocate the space for the Type instance. michael@0: michael@0: DISALLOW_COPY_AND_ASSIGN(LazyInstance); michael@0: }; michael@0: michael@0: } // namespace base michael@0: michael@0: #endif // BASE_LAZY_INSTANCE_H_