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