1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// The LazyInstance<Type, Traits> class manages a single instance of Type, 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// which will be lazily created on the first time it's accessed. This class is 7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// useful for places you would normally use a function-level static, but you 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// need to have guaranteed thread-safety. The Type constructor will only ever 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// be called once, even if two threads are racing to create the object. Get() 10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// and Pointer() will always return the same, completely initialized instance. 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// When the instance is constructed it is registered with AtExitManager. The 12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// destructor will be called on program exit. 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// LazyInstance is completely thread safe, assuming that you create it safely. 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// The class was designed to be POD initialized, so it shouldn't require a 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static constructor. It really only makes sense to declare a LazyInstance as 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// a global variable using the base::LinkerInitialized constructor. 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// LazyInstance is similar to Singleton, except it does not have the singleton 20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// property. You can have multiple LazyInstance's of the same type, and each 21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// will manage a unique instance. It also preallocates the space for Type, as 22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// to avoid allocating the Type instance on the heap. This may help with the 23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// performance of creating the instance, and reducing heap fragmentation. This 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// requires that Type be a complete type so we can determine the size. 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Example usage: 27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// static LazyInstance<MyClass> my_instance(base::LINKER_INITIALIZED); 28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// void SomeMethod() { 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// my_instance.Get().SomeMethod(); // MyClass::SomeMethod() 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// MyClass* ptr = my_instance.Pointer(); 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// ptr->DoDoDo(); // MyClass::DoDoDo 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// } 34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifndef BASE_LAZY_INSTANCE_H_ 36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define BASE_LAZY_INSTANCE_H_ 373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once 38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 39201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include <new> // For placement new. 40201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/atomicops.h" 42ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/base_api.h" 43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/basictypes.h" 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/third_party/dynamic_annotations/dynamic_annotations.h" 453f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/threading/thread_restrictions.h" 46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace base { 48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <typename Type> 50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstruct DefaultLazyInstanceTraits { 51201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static const bool kAllowedToAccessOnNonjoinableThread = false; 52201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static Type* New(void* instance) { 54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Use placement new to initialize our instance in our preallocated space. 55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The parenthesis is very important here to force POD type initialization. 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return new (instance) Type(); 57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static void Delete(void* instance) { 59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Explicitly call the destructor. 60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott reinterpret_cast<Type*>(instance)->~Type(); 61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 64731df977c0511bca2206b5f333555b1205ff1f43Iain Merricktemplate <typename Type> 65731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickstruct LeakyLazyInstanceTraits { 66201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch static const bool kAllowedToAccessOnNonjoinableThread = true; 67201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 68731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick static Type* New(void* instance) { 69731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return DefaultLazyInstanceTraits<Type>::New(instance); 70731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick } 71731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Rather than define an empty Delete function, we make Delete itself 72731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // a null pointer. This allows us to completely sidestep registering 73731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // this object with an AtExitManager, which allows you to use 74731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // LeakyLazyInstanceTraits in contexts where you don't have an 75731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // AtExitManager. 76731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick static void (*Delete)(void* instance); 77731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}; 78731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 79731df977c0511bca2206b5f333555b1205ff1f43Iain Merricktemplate <typename Type> 80731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid (*LeakyLazyInstanceTraits<Type>::Delete)(void* instance) = NULL; 81731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// We pull out some of the functionality into a non-templated base, so that we 83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// can implement the more complicated pieces out of line in the .cc file. 84ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass BASE_API LazyInstanceHelper { 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott protected: 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott enum { 87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott STATE_EMPTY = 0, 88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott STATE_CREATING = 1, 89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott STATE_CREATED = 2 90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 92dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen explicit LazyInstanceHelper(LinkerInitialized /*unused*/) {/* state_ is 0 */} 93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Declaring a destructor (even if it's empty) will cause MSVC to register a 94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // static initializer to register the empty destructor with atexit(). 95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Check if instance needs to be created. If so return true otherwise 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // if another thread has beat us, wait for instance to be created and 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // return false. 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool NeedsInstance(); 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // After creating an instance, call this to register the dtor to be called 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // at program exit and to update the state to STATE_CREATED. 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void CompleteInstance(void* instance, void (*dtor)(void*)); 104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott base::subtle::Atomic32 state_; 106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DISALLOW_COPY_AND_ASSIGN(LazyInstanceHelper); 109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1115dd41b50fc7d24c103522171ec2b3b89b7c0d37fPaul Lind// Allow preservation of object alignment in the lazy instance when using GCC. 1125dd41b50fc7d24c103522171ec2b3b89b7c0d37fPaul Lind// __alignof__ is only defined for GCC > 4.2. 1135dd41b50fc7d24c103522171ec2b3b89b7c0d37fPaul Lind#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 2)) 1145dd41b50fc7d24c103522171ec2b3b89b7c0d37fPaul Lind#define LAZY_ALIGN(T) __attribute__((aligned(__alignof__(T)))) 1155dd41b50fc7d24c103522171ec2b3b89b7c0d37fPaul Lind#else 1165dd41b50fc7d24c103522171ec2b3b89b7c0d37fPaul Lind#define LAZY_ALIGN(T) 1175dd41b50fc7d24c103522171ec2b3b89b7c0d37fPaul Lind#endif 1185dd41b50fc7d24c103522171ec2b3b89b7c0d37fPaul Lind 119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <typename Type, typename Traits = DefaultLazyInstanceTraits<Type> > 120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass LazyInstance : public LazyInstanceHelper { 121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott explicit LazyInstance(LinkerInitialized x) : LazyInstanceHelper(x) { } 123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Declaring a destructor (even if it's empty) will cause MSVC to register a 124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // static initializer to register the empty destructor with atexit(). 125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Type& Get() { 127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return *Pointer(); 128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Type* Pointer() { 131201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (!Traits::kAllowedToAccessOnNonjoinableThread) 132201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch base::ThreadRestrictions::AssertSingletonAllowed(); 133201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // We will hopefully have fast access when the instance is already created. 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if ((base::subtle::NoBarrier_Load(&state_) != STATE_CREATED) && 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NeedsInstance()) { 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Create the instance in the space provided by |buf_|. 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch instance_ = Traits::New(buf_); 139dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Traits::Delete will be null for LeakyLazyInstanceTraits 14021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen void (*dtor)(void*) = Traits::Delete; 14121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen CompleteInstance(this, (dtor == NULL) ? NULL : OnExit); 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // This annotation helps race detectors recognize correct lock-less 145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // synchronization between different threads calling Pointer(). 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We suggest dynamic race detection tool that "Traits::New" above 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // and CompleteInstance(...) happens before "return instance_" below. 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // See the corresponding HAPPENS_BEFORE in CompleteInstance(...). 149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ANNOTATE_HAPPENS_AFTER(&state_); 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return instance_; 151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 153dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen bool operator==(Type* p) { 154dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen switch (base::subtle::NoBarrier_Load(&state_)) { 155dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen case STATE_EMPTY: 156dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return p == NULL; 157dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen case STATE_CREATING: 158dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return static_cast<int8*>(static_cast<void*>(p)) == buf_; 159dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen case STATE_CREATED: 160dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return p == instance_; 161dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen default: 162dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return false; 163dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 164dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 165dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 16721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Adapter function for use with AtExit. This should be called single 16821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // threaded, so don't use atomic operations. 16921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Calling OnExit while the instance is in use by other threads is a mistake. 17021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen static void OnExit(void* lazy_instance) { 17121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen LazyInstance<Type, Traits>* me = 17221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen reinterpret_cast<LazyInstance<Type, Traits>*>(lazy_instance); 17321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen Traits::Delete(me->instance_); 17421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen me->instance_ = NULL; 17521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen base::subtle::Release_Store(&me->state_, STATE_EMPTY); 17621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 17721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 1785dd41b50fc7d24c103522171ec2b3b89b7c0d37fPaul Lind // Preallocate the space for the Type instance, and preserve alignment. 1795dd41b50fc7d24c103522171ec2b3b89b7c0d37fPaul Lind int8 buf_[sizeof(Type)] LAZY_ALIGN(Type); 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Type *instance_; 181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DISALLOW_COPY_AND_ASSIGN(LazyInstance); 183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 1855dd41b50fc7d24c103522171ec2b3b89b7c0d37fPaul Lind#undef LAZY_ALIGN 1865dd41b50fc7d24c103522171ec2b3b89b7c0d37fPaul Lind 187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace base 188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif // BASE_LAZY_INSTANCE_H_ 190