| Index: base/lazy_instance.h
|
| diff --git a/base/lazy_instance.h b/base/lazy_instance.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..f86dc3172aa869676766174b85cd51fcf71122e7
|
| --- /dev/null
|
| +++ b/base/lazy_instance.h
|
| @@ -0,0 +1,183 @@
|
| +// Copyright 2008 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +// The LazyInstance<Type, Traits> class manages a single instance of Type,
|
| +// which will be lazily created on the first time it's accessed. This class is
|
| +// useful for places you would normally use a function-level static, but you
|
| +// need to have guaranteed thread-safety. The Type constructor will only ever
|
| +// be called once, even if two threads are racing to create the object. Get()
|
| +// and Pointer() will always return the same, completely initialized instance.
|
| +//
|
| +// LazyInstance is completely thread safe, assuming that you create it safely.
|
| +// The class was designed to be POD initialized, so it shouldn't require a
|
| +// static constructor. It really only makes sense to declare a LazyInstance as
|
| +// a global variable using the LAZY_INSTANCE_INITIALIZER initializer.
|
| +//
|
| +// LazyInstance is similar to Singleton, except it does not have the singleton
|
| +// property. You can have multiple LazyInstance's of the same type, and each
|
| +// will manage a unique instance. It also preallocates the space for Type, as
|
| +// to avoid allocating the Type instance on the heap. This may help with the
|
| +// performance of creating the instance, and reducing heap fragmentation. This
|
| +// requires that Type be a complete type so we can determine the size.
|
| +//
|
| +// Example usage:
|
| +// static LazyInstance<MyClass> my_instance = LAZY_INSTANCE_INITIALIZER;
|
| +// void SomeMethod() {
|
| +// my_instance.Get().SomeMethod(); // MyClass::SomeMethod()
|
| +//
|
| +// MyClass* ptr = my_instance.Pointer();
|
| +// ptr->DoDoDo(); // MyClass::DoDoDo
|
| +// }
|
| +
|
| +#ifndef MINI_CHROMIUM_BASE_LAZY_INSTANCE_H_
|
| +#define MINI_CHROMIUM_BASE_LAZY_INSTANCE_H_
|
| +
|
| +#include <new>
|
| +
|
| +#include "base/atomicops.h"
|
| +#include "base/basictypes.h"
|
| +#include "base/logging.h"
|
| +#include "base/memory/aligned_memory.h"
|
| +
|
| +// LazyInstance uses its own struct initializer-list style static
|
| +// initialization, as base's LINKER_INITIALIZED requires a constructor and on
|
| +// some compilers (notably gcc 4.4) this still ends up needing runtime
|
| +// initialization.
|
| +#define LAZY_INSTANCE_INITIALIZER {0}
|
| +
|
| +namespace base {
|
| +
|
| +template <typename Type>
|
| +struct DefaultLazyInstanceTraits {
|
| + // mini_chromium does not support Traits::kRegisterOnExit = true because it
|
| + // does not provide AtExitManager. Only LeakyLazyInstanceTraits is supported.
|
| + static const bool kRegisterOnExit = true;
|
| +
|
| + static Type* New(void* instance) {
|
| + DCHECK_EQ(reinterpret_cast<uintptr_t>(instance) & (ALIGNOF(Type) - 1), 0u);
|
| + // Use placement new to initialize our instance in our preallocated space.
|
| + // The parenthesis is very important here to force POD type initialization.
|
| + return new (instance) Type();
|
| + }
|
| + static void Delete(Type* instance) {
|
| + // Explicitly call the destructor.
|
| + instance->~Type();
|
| + }
|
| +};
|
| +
|
| +// We pull out some of the functionality into non-templated functions, so we
|
| +// can implement the more complicated pieces out of line in the .cc file.
|
| +namespace internal {
|
| +
|
| +// Use LazyInstance<T>::Leaky for a less-verbose call-site typedef; e.g.:
|
| +// base::LazyInstance<T>::Leaky my_leaky_lazy_instance;
|
| +// instead of:
|
| +// base::LazyInstance<T, base::internal::LeakyLazyInstanceTraits<T> >
|
| +// my_leaky_lazy_instance;
|
| +// (especially when T is MyLongTypeNameImplClientHolderFactory).
|
| +// Only use this internal::-qualified verbose form to extend this traits class
|
| +// (depending on its implementation details).
|
| +template <typename Type>
|
| +struct LeakyLazyInstanceTraits {
|
| + static const bool kRegisterOnExit = false;
|
| +
|
| + static Type* New(void* instance) {
|
| + return DefaultLazyInstanceTraits<Type>::New(instance);
|
| + }
|
| + static void Delete(Type* instance) {
|
| + }
|
| +};
|
| +
|
| +// Our AtomicWord doubles as a spinlock, where a value of
|
| +// kBeingCreatedMarker means the spinlock is being held for creation.
|
| +static const subtle::AtomicWord kLazyInstanceStateCreating = 1;
|
| +
|
| +// Check if instance needs to be created. If so return true otherwise
|
| +// if another thread has beat us, wait for instance to be created and
|
| +// return false.
|
| +bool NeedsLazyInstance(subtle::AtomicWord* state);
|
| +
|
| +// After creating an instance, call this to register the dtor to be called
|
| +// at program exit and to update the atomic state to hold the |new_instance|
|
| +void CompleteLazyInstance(subtle::AtomicWord* state,
|
| + subtle::AtomicWord new_instance,
|
| + void* lazy_instance);
|
| +
|
| +} // namespace internal
|
| +
|
| +template <typename Type, typename Traits = DefaultLazyInstanceTraits<Type> >
|
| +class LazyInstance {
|
| + public:
|
| + // Do not define a destructor, as doing so makes LazyInstance a
|
| + // non-POD-struct. We don't want that because then a static initializer will
|
| + // be created to register the (empty) destructor with atexit() under MSVC, for
|
| + // example.
|
| + // ~LazyInstance() {}
|
| +
|
| + // Convenience typedef to avoid having to repeat Type for leaky lazy
|
| + // instances.
|
| + typedef LazyInstance<Type, internal::LeakyLazyInstanceTraits<Type> > Leaky;
|
| +
|
| + Type& Get() {
|
| + return *Pointer();
|
| + }
|
| +
|
| + Type* Pointer() {
|
| + // If any bit in the created mask is true, the instance has already been
|
| + // fully constructed.
|
| + static const subtle::AtomicWord kLazyInstanceCreatedMask =
|
| + ~internal::kLazyInstanceStateCreating;
|
| +
|
| + // We will hopefully have fast access when the instance is already created.
|
| + // Since a thread sees private_instance_ == 0 or kLazyInstanceStateCreating
|
| + // at most once, the load is taken out of NeedsInstance() as a fast-path.
|
| + // The load has acquire memory ordering as a thread which sees
|
| + // private_instance_ > creating needs to acquire visibility over
|
| + // the associated data (private_buf_). Pairing Release_Store is in
|
| + // CompleteLazyInstance().
|
| + subtle::AtomicWord value = subtle::Acquire_Load(&private_instance_);
|
| + if (!(value & kLazyInstanceCreatedMask) &&
|
| + internal::NeedsLazyInstance(&private_instance_)) {
|
| + // Create the instance in the space provided by |private_buf_|.
|
| + value = reinterpret_cast<subtle::AtomicWord>(
|
| + Traits::New(private_buf_.void_data()));
|
| + internal::CompleteLazyInstance(&private_instance_, value, this);
|
| +
|
| + // mini_chromium does not support Traits::kRegisterOnExit = true because
|
| + // it does not provide AtExitManager. Instead of LazyInstanceTraits, use
|
| + // LeakyLazyInstanceTraits, and note that destructors will not run.
|
| + static_assert(!Traits::kRegisterOnExit,
|
| + "destruction not supported in mini_chromium");
|
| + }
|
| + return instance();
|
| + }
|
| +
|
| + bool operator==(Type* p) {
|
| + switch (subtle::NoBarrier_Load(&private_instance_)) {
|
| + case 0:
|
| + return p == NULL;
|
| + case internal::kLazyInstanceStateCreating:
|
| + return static_cast<void*>(p) == private_buf_.void_data();
|
| + default:
|
| + return p == instance();
|
| + }
|
| + }
|
| +
|
| + // Effectively private: member data is only public to allow the linker to
|
| + // statically initialize it and to maintain a POD class. DO NOT USE FROM
|
| + // OUTSIDE THIS CLASS.
|
| +
|
| + subtle::AtomicWord private_instance_;
|
| + // Preallocated space for the Type instance.
|
| + base::AlignedMemory<sizeof(Type), ALIGNOF(Type)> private_buf_;
|
| +
|
| + private:
|
| + Type* instance() {
|
| + return reinterpret_cast<Type*>(subtle::NoBarrier_Load(&private_instance_));
|
| + }
|
| +};
|
| +
|
| +} // namespace base
|
| +
|
| +#endif // MINI_CHROMIUM_BASE_LAZY_INSTANCE_H_
|
|
|