ipc/chromium/src/base/lazy_instance.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/ipc/chromium/src/base/lazy_instance.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,110 @@
     1.4 +// Copyright (c) 2008 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 base::LinkerInitialized constructor.
    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(base::LINKER_INITIALIZED);
    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 "base/atomicops.h"
    1.42 +#include "base/basictypes.h"
    1.43 +
    1.44 +namespace base {
    1.45 +
    1.46 +template <typename Type>
    1.47 +struct DefaultLazyInstanceTraits {
    1.48 +  static void New(void* instance) {
    1.49 +    // Use placement new to initialize our instance in our preallocated space.
    1.50 +    // The parenthesis is very important here to force POD type initialization.
    1.51 +    new (instance) Type();
    1.52 +  }
    1.53 +  static void Delete(void* instance) {
    1.54 +    // Explicitly call the destructor.
    1.55 +    reinterpret_cast<Type*>(instance)->~Type();
    1.56 +  }
    1.57 +};
    1.58 +
    1.59 +// We pull out some of the functionality into a non-templated base, so that we
    1.60 +// can implement the more complicated pieces out of line in the .cc file.
    1.61 +class LazyInstanceHelper {
    1.62 + protected:
    1.63 +  enum {
    1.64 +    STATE_EMPTY    = 0,
    1.65 +    STATE_CREATING = 1,
    1.66 +    STATE_CREATED  = 2
    1.67 +  };
    1.68 +
    1.69 +  explicit LazyInstanceHelper(LinkerInitialized x) { /* state_ is 0 */ }
    1.70 +  // Declaring a destructor (even if it's empty) will cause MSVC to register a
    1.71 +  // static initializer to register the empty destructor with atexit().
    1.72 +
    1.73 +  // Make sure that instance is created, creating or waiting for it to be
    1.74 +  // created if neccessary.  Constructs with |ctor| in the space provided by
    1.75 +  // |instance| and registers dtor for destruction at program exit.
    1.76 +  void EnsureInstance(void* instance, void (*ctor)(void*), void (*dtor)(void*));
    1.77 +
    1.78 +  base::subtle::Atomic32 state_;
    1.79 +
    1.80 + private:
    1.81 +  DISALLOW_COPY_AND_ASSIGN(LazyInstanceHelper);
    1.82 +};
    1.83 +
    1.84 +template <typename Type, typename Traits = DefaultLazyInstanceTraits<Type> >
    1.85 +class LazyInstance : public LazyInstanceHelper {
    1.86 + public:
    1.87 +  explicit LazyInstance(LinkerInitialized x) : LazyInstanceHelper(x) { }
    1.88 +  // Declaring a destructor (even if it's empty) will cause MSVC to register a
    1.89 +  // static initializer to register the empty destructor with atexit().
    1.90 +
    1.91 +  Type& Get() {
    1.92 +    return *Pointer();
    1.93 +  }
    1.94 +
    1.95 +  Type* Pointer() {
    1.96 +    Type* instance = reinterpret_cast<Type*>(&buf_);
    1.97 +
    1.98 +    // We will hopefully have fast access when the instance is already created.
    1.99 +    if (base::subtle::NoBarrier_Load(&state_) != STATE_CREATED)
   1.100 +      EnsureInstance(instance, Traits::New, Traits::Delete);
   1.101 +
   1.102 +    return instance;
   1.103 +  }
   1.104 +
   1.105 + private:
   1.106 +  int8_t buf_[sizeof(Type)];  // Preallocate the space for the Type instance.
   1.107 +
   1.108 +  DISALLOW_COPY_AND_ASSIGN(LazyInstance);
   1.109 +};
   1.110 +
   1.111 +}  // namespace base
   1.112 +
   1.113 +#endif  // BASE_LAZY_INSTANCE_H_

mercurial