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