lazy_instance.h revision 5821806d5e7f356e8fa4b058a389a808ea183019
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The LazyInstance<Type, Traits> class manages a single instance of Type, 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// which will be lazily created on the first time it's accessed. This class is 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// useful for places you would normally use a function-level static, but you 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// need to have guaranteed thread-safety. The Type constructor will only ever 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// be called once, even if two threads are racing to create the object. Get() 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and Pointer() will always return the same, completely initialized instance. 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// When the instance is constructed it is registered with AtExitManager. The 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// destructor will be called on program exit. 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LazyInstance is completely thread safe, assuming that you create it safely. 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The class was designed to be POD initialized, so it shouldn't require a 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static constructor. It really only makes sense to declare a LazyInstance as 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a global variable using the LAZY_INSTANCE_INITIALIZER initializer. 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LazyInstance is similar to Singleton, except it does not have the singleton 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// property. You can have multiple LazyInstance's of the same type, and each 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// will manage a unique instance. It also preallocates the space for Type, as 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to avoid allocating the Type instance on the heap. This may help with the 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// performance of creating the instance, and reducing heap fragmentation. This 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// requires that Type be a complete type so we can determine the size. 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Example usage: 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static LazyInstance<MyClass> my_instance = LAZY_INSTANCE_INITIALIZER; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// void SomeMethod() { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// my_instance.Get().SomeMethod(); // MyClass::SomeMethod() 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// MyClass* ptr = my_instance.Pointer(); 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ptr->DoDoDo(); // MyClass::DoDoDo 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// } 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef BASE_LAZY_INSTANCE_H_ 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define BASE_LAZY_INSTANCE_H_ 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <new> // For placement new. 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/atomicops.h" 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/base_export.h" 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/aligned_memory.h" 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/third_party/dynamic_annotations/dynamic_annotations.h" 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread_restrictions.h" 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LazyInstance uses its own struct initializer-list style static 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// initialization, as base's LINKER_INITIALIZED requires a constructor and on 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// some compilers (notably gcc 4.4) this still ends up needing runtime 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// initialization. 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define LAZY_INSTANCE_INITIALIZER {0} 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename Type> 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct DefaultLazyInstanceTraits { 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const bool kRegisterOnExit = true; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const bool kAllowedToAccessOnNonjoinableThread = false; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static Type* New(void* instance) { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(reinterpret_cast<uintptr_t>(instance) & (ALIGNOF(Type) - 1), 0u) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << ": Bad boy, the buffer passed to placement new is not aligned!\n" 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "This may break some stuff like SSE-based optimizations assuming the " 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "<Type> objects are word aligned."; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use placement new to initialize our instance in our preallocated space. 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The parenthesis is very important here to force POD type initialization. 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new (instance) Type(); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void Delete(Type* instance) { 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Explicitly call the destructor. 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) instance->~Type(); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We pull out some of the functionality into non-templated functions, so we 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// can implement the more complicated pieces out of line in the .cc file. 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace internal { 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use LazyInstance<T>::Leaky for a less-verbose call-site typedef; e.g.: 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// base::LazyInstance<T>::Leaky my_leaky_lazy_instance; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// instead of: 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// base::LazyInstance<T, base::internal::LeakyLazyInstanceTraits<T> > 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// my_leaky_lazy_instance; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (especially when T is MyLongTypeNameImplClientHolderFactory). 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Only use this internal::-qualified verbose form to extend this traits class 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (depending on its implementation details). 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename Type> 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct LeakyLazyInstanceTraits { 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const bool kRegisterOnExit = false; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const bool kAllowedToAccessOnNonjoinableThread = true; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static Type* New(void* instance) { 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return DefaultLazyInstanceTraits<Type>::New(instance); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void Delete(Type* instance) { 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Our AtomicWord doubles as a spinlock, where a value of 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// kBeingCreatedMarker means the spinlock is being held for creation. 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const subtle::AtomicWord kLazyInstanceStateCreating = 1; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Check if instance needs to be created. If so return true otherwise 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// if another thread has beat us, wait for instance to be created and 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// return false. 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BASE_EXPORT bool NeedsLazyInstance(subtle::AtomicWord* state); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// After creating an instance, call this to register the dtor to be called 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// at program exit and to update the atomic state to hold the |new_instance| 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BASE_EXPORT void CompleteLazyInstance(subtle::AtomicWord* state, 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) subtle::AtomicWord new_instance, 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* lazy_instance, 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void (*dtor)(void*)); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace internal 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename Type, typename Traits = DefaultLazyInstanceTraits<Type> > 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class LazyInstance { 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Do not define a destructor, as doing so makes LazyInstance a 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // non-POD-struct. We don't want that because then a static initializer will 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be created to register the (empty) destructor with atexit() under MSVC, for 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // example. We handle destruction of the contained Type class explicitly via 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the OnExit member function, where needed. 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ~LazyInstance() {} 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Convenience typedef to avoid having to repeat Type for leaky lazy 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // instances. 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef LazyInstance<Type, internal::LeakyLazyInstanceTraits<Type> > Leaky; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Type& Get() { 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return *Pointer(); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Type* Pointer() { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NDEBUG 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Avoid making TLS lookup on release builds. 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!Traits::kAllowedToAccessOnNonjoinableThread) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ThreadRestrictions::AssertSingletonAllowed(); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If any bit in the created mask is true, the instance has already been 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // fully constructed. 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const subtle::AtomicWord kLazyInstanceCreatedMask = 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~internal::kLazyInstanceStateCreating; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We will hopefully have fast access when the instance is already created. 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Since a thread sees private_instance_ == 0 or kLazyInstanceStateCreating 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // at most once, the load is taken out of NeedsInstance() as a fast-path. 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The load has acquire memory ordering as a thread which sees 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // private_instance_ > creating needs to acquire visibility over 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the associated data (private_buf_). Pairing Release_Store is in 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // CompleteLazyInstance(). 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) subtle::AtomicWord value = subtle::Acquire_Load(&private_instance_); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(value & kLazyInstanceCreatedMask) && 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) internal::NeedsLazyInstance(&private_instance_)) { 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create the instance in the space provided by |private_buf_|. 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = reinterpret_cast<subtle::AtomicWord>( 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Traits::New(private_buf_.void_data())); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) internal::CompleteLazyInstance(&private_instance_, value, this, 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Traits::kRegisterOnExit ? OnExit : NULL); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This annotation helps race detectors recognize correct lock-less 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // synchronization between different threads calling Pointer(). 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We suggest dynamic race detection tool that "Traits::New" above 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and CompleteLazyInstance(...) happens before "return instance()" below. 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See the corresponding HAPPENS_BEFORE in CompleteLazyInstance(...). 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ANNOTATE_HAPPENS_AFTER(&private_instance_); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return instance(); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool operator==(Type* p) { 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (subtle::NoBarrier_Load(&private_instance_)) { 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 0: 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return p == NULL; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case internal::kLazyInstanceStateCreating: 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return static_cast<void*>(p) == private_buf_.void_data(); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return p == instance(); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Effectively private: member data is only public to allow the linker to 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // statically initialize it and to maintain a POD class. DO NOT USE FROM 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // OUTSIDE THIS CLASS. 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) subtle::AtomicWord private_instance_; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Preallocated space for the Type instance. 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AlignedMemory<sizeof(Type), ALIGNOF(Type)> private_buf_; 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Type* instance() { 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return reinterpret_cast<Type*>(subtle::NoBarrier_Load(&private_instance_)); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Adapter function for use with AtExit. This should be called single 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // threaded, so don't synchronize across threads. 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Calling OnExit while the instance is in use by other threads is a mistake. 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void OnExit(void* lazy_instance) { 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LazyInstance<Type, Traits>* me = 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<LazyInstance<Type, Traits>*>(lazy_instance); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Traits::Delete(me->instance()); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) subtle::NoBarrier_Store(&me->private_instance_, 0); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace base 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // BASE_LAZY_INSTANCE_H_ 211