security/sandbox/chromium/base/lazy_instance.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/security/sandbox/chromium/base/lazy_instance.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,212 @@
     1.4 +// Copyright (c) 2012 The Chromium Authors. All rights reserved.
     1.5 +// Use of this source code is governed by a BSD-style license that can be
     1.6 +// found in the LICENSE file.
     1.7 +
     1.8 +// The LazyInstance<Type, Traits> class manages a single instance of Type,
     1.9 +// which will be lazily created on the first time it's accessed.  This class is
    1.10 +// useful for places you would normally use a function-level static, but you
    1.11 +// need to have guaranteed thread-safety.  The Type constructor will only ever
    1.12 +// be called once, even if two threads are racing to create the object.  Get()
    1.13 +// and Pointer() will always return the same, completely initialized instance.
    1.14 +// When the instance is constructed it is registered with AtExitManager.  The
    1.15 +// destructor will be called on program exit.
    1.16 +//
    1.17 +// LazyInstance is completely thread safe, assuming that you create it safely.
    1.18 +// The class was designed to be POD initialized, so it shouldn't require a
    1.19 +// static constructor.  It really only makes sense to declare a LazyInstance as
    1.20 +// a global variable using the LAZY_INSTANCE_INITIALIZER initializer.
    1.21 +//
    1.22 +// LazyInstance is similar to Singleton, except it does not have the singleton
    1.23 +// property.  You can have multiple LazyInstance's of the same type, and each
    1.24 +// will manage a unique instance.  It also preallocates the space for Type, as
    1.25 +// to avoid allocating the Type instance on the heap.  This may help with the
    1.26 +// performance of creating the instance, and reducing heap fragmentation.  This
    1.27 +// requires that Type be a complete type so we can determine the size.
    1.28 +//
    1.29 +// Example usage:
    1.30 +//   static LazyInstance<MyClass> my_instance = LAZY_INSTANCE_INITIALIZER;
    1.31 +//   void SomeMethod() {
    1.32 +//     my_instance.Get().SomeMethod();  // MyClass::SomeMethod()
    1.33 +//
    1.34 +//     MyClass* ptr = my_instance.Pointer();
    1.35 +//     ptr->DoDoDo();  // MyClass::DoDoDo
    1.36 +//   }
    1.37 +
    1.38 +#ifndef BASE_LAZY_INSTANCE_H_
    1.39 +#define BASE_LAZY_INSTANCE_H_
    1.40 +
    1.41 +#include <new>  // For placement new.
    1.42 +
    1.43 +#include "base/atomicops.h"
    1.44 +#include "base/base_export.h"
    1.45 +#include "base/basictypes.h"
    1.46 +#include "base/debug/leak_annotations.h"
    1.47 +#include "base/logging.h"
    1.48 +#include "base/memory/aligned_memory.h"
    1.49 +#include "base/third_party/dynamic_annotations/dynamic_annotations.h"
    1.50 +#include "base/threading/thread_restrictions.h"
    1.51 +
    1.52 +// LazyInstance uses its own struct initializer-list style static
    1.53 +// initialization, as base's LINKER_INITIALIZED requires a constructor and on
    1.54 +// some compilers (notably gcc 4.4) this still ends up needing runtime
    1.55 +// initialization.
    1.56 +#define LAZY_INSTANCE_INITIALIZER {0}
    1.57 +
    1.58 +namespace base {
    1.59 +
    1.60 +template <typename Type>
    1.61 +struct DefaultLazyInstanceTraits {
    1.62 +  static const bool kRegisterOnExit = true;
    1.63 +  static const bool kAllowedToAccessOnNonjoinableThread = false;
    1.64 +
    1.65 +  static Type* New(void* instance) {
    1.66 +    DCHECK_EQ(reinterpret_cast<uintptr_t>(instance) & (ALIGNOF(Type) - 1), 0u)
    1.67 +        << ": Bad boy, the buffer passed to placement new is not aligned!\n"
    1.68 +        "This may break some stuff like SSE-based optimizations assuming the "
    1.69 +        "<Type> objects are word aligned.";
    1.70 +    // Use placement new to initialize our instance in our preallocated space.
    1.71 +    // The parenthesis is very important here to force POD type initialization.
    1.72 +    return new (instance) Type();
    1.73 +  }
    1.74 +  static void Delete(Type* instance) {
    1.75 +    // Explicitly call the destructor.
    1.76 +    instance->~Type();
    1.77 +  }
    1.78 +};
    1.79 +
    1.80 +// We pull out some of the functionality into non-templated functions, so we
    1.81 +// can implement the more complicated pieces out of line in the .cc file.
    1.82 +namespace internal {
    1.83 +
    1.84 +// Use LazyInstance<T>::Leaky for a less-verbose call-site typedef; e.g.:
    1.85 +// base::LazyInstance<T>::Leaky my_leaky_lazy_instance;
    1.86 +// instead of:
    1.87 +// base::LazyInstance<T, base::internal::LeakyLazyInstanceTraits<T> >
    1.88 +// my_leaky_lazy_instance;
    1.89 +// (especially when T is MyLongTypeNameImplClientHolderFactory).
    1.90 +// Only use this internal::-qualified verbose form to extend this traits class
    1.91 +// (depending on its implementation details).
    1.92 +template <typename Type>
    1.93 +struct LeakyLazyInstanceTraits {
    1.94 +  static const bool kRegisterOnExit = false;
    1.95 +  static const bool kAllowedToAccessOnNonjoinableThread = true;
    1.96 +
    1.97 +  static Type* New(void* instance) {
    1.98 +    ANNOTATE_SCOPED_MEMORY_LEAK;
    1.99 +    return DefaultLazyInstanceTraits<Type>::New(instance);
   1.100 +  }
   1.101 +  static void Delete(Type* instance) {
   1.102 +  }
   1.103 +};
   1.104 +
   1.105 +// Our AtomicWord doubles as a spinlock, where a value of
   1.106 +// kBeingCreatedMarker means the spinlock is being held for creation.
   1.107 +static const subtle::AtomicWord kLazyInstanceStateCreating = 1;
   1.108 +
   1.109 +// Check if instance needs to be created. If so return true otherwise
   1.110 +// if another thread has beat us, wait for instance to be created and
   1.111 +// return false.
   1.112 +BASE_EXPORT bool NeedsLazyInstance(subtle::AtomicWord* state);
   1.113 +
   1.114 +// After creating an instance, call this to register the dtor to be called
   1.115 +// at program exit and to update the atomic state to hold the |new_instance|
   1.116 +BASE_EXPORT void CompleteLazyInstance(subtle::AtomicWord* state,
   1.117 +                                      subtle::AtomicWord new_instance,
   1.118 +                                      void* lazy_instance,
   1.119 +                                      void (*dtor)(void*));
   1.120 +
   1.121 +}  // namespace internal
   1.122 +
   1.123 +template <typename Type, typename Traits = DefaultLazyInstanceTraits<Type> >
   1.124 +class LazyInstance {
   1.125 + public:
   1.126 +  // Do not define a destructor, as doing so makes LazyInstance a
   1.127 +  // non-POD-struct. We don't want that because then a static initializer will
   1.128 +  // be created to register the (empty) destructor with atexit() under MSVC, for
   1.129 +  // example. We handle destruction of the contained Type class explicitly via
   1.130 +  // the OnExit member function, where needed.
   1.131 +  // ~LazyInstance() {}
   1.132 +
   1.133 +  // Convenience typedef to avoid having to repeat Type for leaky lazy
   1.134 +  // instances.
   1.135 +  typedef LazyInstance<Type, internal::LeakyLazyInstanceTraits<Type> > Leaky;
   1.136 +
   1.137 +  Type& Get() {
   1.138 +    return *Pointer();
   1.139 +  }
   1.140 +
   1.141 +  Type* Pointer() {
   1.142 +#ifndef NDEBUG
   1.143 +    // Avoid making TLS lookup on release builds.
   1.144 +    if (!Traits::kAllowedToAccessOnNonjoinableThread)
   1.145 +      ThreadRestrictions::AssertSingletonAllowed();
   1.146 +#endif
   1.147 +    // If any bit in the created mask is true, the instance has already been
   1.148 +    // fully constructed.
   1.149 +    static const subtle::AtomicWord kLazyInstanceCreatedMask =
   1.150 +        ~internal::kLazyInstanceStateCreating;
   1.151 +
   1.152 +    // We will hopefully have fast access when the instance is already created.
   1.153 +    // Since a thread sees private_instance_ == 0 or kLazyInstanceStateCreating
   1.154 +    // at most once, the load is taken out of NeedsInstance() as a fast-path.
   1.155 +    // The load has acquire memory ordering as a thread which sees
   1.156 +    // private_instance_ > creating needs to acquire visibility over
   1.157 +    // the associated data (private_buf_). Pairing Release_Store is in
   1.158 +    // CompleteLazyInstance().
   1.159 +    subtle::AtomicWord value = subtle::Acquire_Load(&private_instance_);
   1.160 +    if (!(value & kLazyInstanceCreatedMask) &&
   1.161 +        internal::NeedsLazyInstance(&private_instance_)) {
   1.162 +      // Create the instance in the space provided by |private_buf_|.
   1.163 +      value = reinterpret_cast<subtle::AtomicWord>(
   1.164 +          Traits::New(private_buf_.void_data()));
   1.165 +      internal::CompleteLazyInstance(&private_instance_, value, this,
   1.166 +                                     Traits::kRegisterOnExit ? OnExit : NULL);
   1.167 +    }
   1.168 +
   1.169 +    // This annotation helps race detectors recognize correct lock-less
   1.170 +    // synchronization between different threads calling Pointer().
   1.171 +    // We suggest dynamic race detection tool that "Traits::New" above
   1.172 +    // and CompleteLazyInstance(...) happens before "return instance()" below.
   1.173 +    // See the corresponding HAPPENS_BEFORE in CompleteLazyInstance(...).
   1.174 +    ANNOTATE_HAPPENS_AFTER(&private_instance_);
   1.175 +    return instance();
   1.176 +  }
   1.177 +
   1.178 +  bool operator==(Type* p) {
   1.179 +    switch (subtle::NoBarrier_Load(&private_instance_)) {
   1.180 +      case 0:
   1.181 +        return p == NULL;
   1.182 +      case internal::kLazyInstanceStateCreating:
   1.183 +        return static_cast<void*>(p) == private_buf_.void_data();
   1.184 +      default:
   1.185 +        return p == instance();
   1.186 +    }
   1.187 +  }
   1.188 +
   1.189 +  // Effectively private: member data is only public to allow the linker to
   1.190 +  // statically initialize it and to maintain a POD class. DO NOT USE FROM
   1.191 +  // OUTSIDE THIS CLASS.
   1.192 +
   1.193 +  subtle::AtomicWord private_instance_;
   1.194 +  // Preallocated space for the Type instance.
   1.195 +  base::AlignedMemory<sizeof(Type), ALIGNOF(Type)> private_buf_;
   1.196 +
   1.197 + private:
   1.198 +  Type* instance() {
   1.199 +    return reinterpret_cast<Type*>(subtle::NoBarrier_Load(&private_instance_));
   1.200 +  }
   1.201 +
   1.202 +  // Adapter function for use with AtExit.  This should be called single
   1.203 +  // threaded, so don't synchronize across threads.
   1.204 +  // Calling OnExit while the instance is in use by other threads is a mistake.
   1.205 +  static void OnExit(void* lazy_instance) {
   1.206 +    LazyInstance<Type, Traits>* me =
   1.207 +        reinterpret_cast<LazyInstance<Type, Traits>*>(lazy_instance);
   1.208 +    Traits::Delete(me->instance());
   1.209 +    subtle::NoBarrier_Store(&me->private_instance_, 0);
   1.210 +  }
   1.211 +};
   1.212 +
   1.213 +}  // namespace base
   1.214 +
   1.215 +#endif  // BASE_LAZY_INSTANCE_H_

mercurial