Home | History | Annotate | Download | only in base
      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