lazy_instance.h revision dc0f95d653279beabeb9817299e2902918ba123e
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#pragma once
38
39#include <new>  // For placement new.
40
41#include "base/atomicops.h"
42#include "base/basictypes.h"
43#include "base/third_party/dynamic_annotations/dynamic_annotations.h"
44#include "base/threading/thread_restrictions.h"
45
46namespace base {
47
48template <typename Type>
49struct DefaultLazyInstanceTraits {
50  static const bool kAllowedToAccessOnNonjoinableThread = false;
51
52  static Type* New(void* instance) {
53    // Use placement new to initialize our instance in our preallocated space.
54    // The parenthesis is very important here to force POD type initialization.
55    return new (instance) Type();
56  }
57  static void Delete(void* instance) {
58    // Explicitly call the destructor.
59    reinterpret_cast<Type*>(instance)->~Type();
60  }
61};
62
63template <typename Type>
64struct LeakyLazyInstanceTraits {
65  static const bool kAllowedToAccessOnNonjoinableThread = true;
66
67  static Type* New(void* instance) {
68    return DefaultLazyInstanceTraits<Type>::New(instance);
69  }
70  // Rather than define an empty Delete function, we make Delete itself
71  // a null pointer.  This allows us to completely sidestep registering
72  // this object with an AtExitManager, which allows you to use
73  // LeakyLazyInstanceTraits in contexts where you don't have an
74  // AtExitManager.
75  static void (*Delete)(void* instance);
76};
77
78template <typename Type>
79void (*LeakyLazyInstanceTraits<Type>::Delete)(void* instance) = NULL;
80
81// We pull out some of the functionality into a non-templated base, so that we
82// can implement the more complicated pieces out of line in the .cc file.
83class LazyInstanceHelper {
84 protected:
85  enum {
86    STATE_EMPTY    = 0,
87    STATE_CREATING = 1,
88    STATE_CREATED  = 2
89  };
90
91  explicit LazyInstanceHelper(LinkerInitialized /*unused*/) {/* state_ is 0 */}
92  // Declaring a destructor (even if it's empty) will cause MSVC to register a
93  // static initializer to register the empty destructor with atexit().
94
95  // Check if instance needs to be created. If so return true otherwise
96  // if another thread has beat us, wait for instance to be created and
97  // return false.
98  bool NeedsInstance();
99
100  // After creating an instance, call this to register the dtor to be called
101  // at program exit and to update the state to STATE_CREATED.
102  void CompleteInstance(void* instance, void (*dtor)(void*));
103
104  base::subtle::Atomic32 state_;
105
106 private:
107  DISALLOW_COPY_AND_ASSIGN(LazyInstanceHelper);
108};
109
110template <typename Type, typename Traits = DefaultLazyInstanceTraits<Type> >
111class LazyInstance : public LazyInstanceHelper {
112 public:
113  explicit LazyInstance(LinkerInitialized x) : LazyInstanceHelper(x) { }
114  // Declaring a destructor (even if it's empty) will cause MSVC to register a
115  // static initializer to register the empty destructor with atexit().
116
117  Type& Get() {
118    return *Pointer();
119  }
120
121  Type* Pointer() {
122    if (!Traits::kAllowedToAccessOnNonjoinableThread)
123      base::ThreadRestrictions::AssertSingletonAllowed();
124
125    // We will hopefully have fast access when the instance is already created.
126    if ((base::subtle::NoBarrier_Load(&state_) != STATE_CREATED) &&
127        NeedsInstance()) {
128      // Create the instance in the space provided by |buf_|.
129      instance_ = Traits::New(buf_);
130      // Traits::Delete will be null for LeakyLazyInstanceTraits
131      void (*dtor)(void*) = Traits::Delete;
132      CompleteInstance(this, (dtor == NULL) ? NULL : OnExit);
133    }
134
135    // This annotation helps race detectors recognize correct lock-less
136    // synchronization between different threads calling Pointer().
137    // We suggest dynamic race detection tool that "Traits::New" above
138    // and CompleteInstance(...) happens before "return instance_" below.
139    // See the corresponding HAPPENS_BEFORE in CompleteInstance(...).
140    ANNOTATE_HAPPENS_AFTER(&state_);
141    return instance_;
142  }
143
144  bool operator==(Type* p) {
145    switch (base::subtle::NoBarrier_Load(&state_)) {
146      case STATE_EMPTY:
147        return p == NULL;
148      case STATE_CREATING:
149        return static_cast<int8*>(static_cast<void*>(p)) == buf_;
150      case STATE_CREATED:
151        return p == instance_;
152      default:
153        return false;
154    }
155  }
156
157 private:
158  // Adapter function for use with AtExit.  This should be called single
159  // threaded, so don't use atomic operations.
160  // Calling OnExit while the instance is in use by other threads is a mistake.
161  static void OnExit(void* lazy_instance) {
162    LazyInstance<Type, Traits>* me =
163        reinterpret_cast<LazyInstance<Type, Traits>*>(lazy_instance);
164    Traits::Delete(me->instance_);
165    me->instance_ = NULL;
166    base::subtle::Release_Store(&me->state_, STATE_EMPTY);
167  }
168
169  int8 buf_[sizeof(Type)];  // Preallocate the space for the Type instance.
170  Type *instance_;
171
172  DISALLOW_COPY_AND_ASSIGN(LazyInstance);
173};
174
175}  // namespace base
176
177#endif  // BASE_LAZY_INSTANCE_H_
178