singleton.h 11.7 KB
Newer Older
gejun's avatar
gejun committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
// Copyright (c) 2011 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.

// PLEASE READ: Do you really need a singleton?
//
// Singletons make it hard to determine the lifetime of an object, which can
// lead to buggy code and spurious crashes.
//
// Instead of adding another singleton into the mix, try to identify either:
//   a) An existing singleton that can manage your object's lifetime
//   b) Locations where you can deterministically create the object and pass
//      into other objects
//
// If you absolutely need a singleton, please keep them as trivial as possible
// and ideally a leaf dependency. Singletons get problematic when they attempt
// to do too much in their destructor or have circular dependencies.

19 20
#ifndef BUTIL_MEMORY_SINGLETON_H_
#define BUTIL_MEMORY_SINGLETON_H_
gejun's avatar
gejun committed
21

22 23 24 25 26 27 28 29
#include "butil/at_exit.h"
#include "butil/atomicops.h"
#include "butil/base_export.h"
#include "butil/memory/aligned_memory.h"
#include "butil/third_party/dynamic_annotations/dynamic_annotations.h"
#include "butil/threading/thread_restrictions.h"

namespace butil {
gejun's avatar
gejun committed
30 31 32 33 34 35 36 37
namespace internal {

// Our AtomicWord doubles as a spinlock, where a value of
// kBeingCreatedMarker means the spinlock is being held for creation.
static const subtle::AtomicWord kBeingCreatedMarker = 1;

// We pull out some of the functionality into a non-templated function, so that
// we can implement the more complicated pieces out of line in the .cc file.
38
BUTIL_EXPORT subtle::AtomicWord WaitForInstance(subtle::AtomicWord* instance);
gejun's avatar
gejun committed
39 40

}  // namespace internal
41
}  // namespace butil
gejun's avatar
gejun committed
42

43
// TODO(joth): Move more of this file into namespace butil
gejun's avatar
gejun committed
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127

// Default traits for Singleton<Type>. Calls operator new and operator delete on
// the object. Registers automatic deletion at process exit.
// Overload if you need arguments or another memory allocation function.
template<typename Type>
struct DefaultSingletonTraits {
  // Allocates the object.
  static Type* New() {
    // The parenthesis is very important here; it forces POD type
    // initialization.
    return new Type();
  }

  // Destroys the object.
  static void Delete(Type* x) {
    delete x;
  }

  // Set to true to automatically register deletion of the object on process
  // exit. See below for the required call that makes this happen.
  static const bool kRegisterAtExit;

#ifndef NDEBUG
  // Set to false to disallow access on a non-joinable thread.  This is
  // different from kRegisterAtExit because StaticMemorySingletonTraits allows
  // access on non-joinable threads, and gracefully handles this.
  static const bool kAllowedToAccessOnNonjoinableThread;
#endif
};

// NOTE(gejun): BullseyeCoverage Compile C++ 8.4.4 complains about `undefined
// reference' on in-place assignments to static constants.
template<typename Type>
const bool DefaultSingletonTraits<Type>::kRegisterAtExit = true;
#ifndef NDEBUG
template<typename Type>
const bool DefaultSingletonTraits<Type>::kAllowedToAccessOnNonjoinableThread = false;
#endif

// Alternate traits for use with the Singleton<Type>.  Identical to
// DefaultSingletonTraits except that the Singleton will not be cleaned up
// at exit.
template<typename Type>
struct LeakySingletonTraits : public DefaultSingletonTraits<Type> {
  static const bool kRegisterAtExit;
#ifndef NDEBUG
  static const bool kAllowedToAccessOnNonjoinableThread;
#endif
};

template<typename Type>
const bool LeakySingletonTraits<Type>::kRegisterAtExit = false;
#ifndef NDEBUG
template<typename Type>
const bool LeakySingletonTraits<Type>::kAllowedToAccessOnNonjoinableThread = true;
#endif

// Alternate traits for use with the Singleton<Type>.  Allocates memory
// for the singleton instance from a static buffer.  The singleton will
// be cleaned up at exit, but can't be revived after destruction unless
// the Resurrect() method is called.
//
// This is useful for a certain category of things, notably logging and
// tracing, where the singleton instance is of a type carefully constructed to
// be safe to access post-destruction.
// In logging and tracing you'll typically get stray calls at odd times, like
// during static destruction, thread teardown and the like, and there's a
// termination race on the heap-based singleton - e.g. if one thread calls
// get(), but then another thread initiates AtExit processing, the first thread
// may call into an object residing in unallocated memory. If the instance is
// allocated from the data segment, then this is survivable.
//
// The destructor is to deallocate system resources, in this case to unregister
// a callback the system will invoke when logging levels change. Note that
// this is also used in e.g. Chrome Frame, where you have to allow for the
// possibility of loading briefly into someone else's process space, and
// so leaking is not an option, as that would sabotage the state of your host
// process once you've unloaded.
template <typename Type>
struct StaticMemorySingletonTraits {
  // WARNING: User has to deal with get() in the singleton class
  // this is traits for returning NULL.
  static Type* New() {
    // Only constructs once and returns pointer; otherwise returns NULL.
128
    if (butil::subtle::NoBarrier_AtomicExchange(&dead_, 1))
gejun's avatar
gejun committed
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
      return NULL;

    return new(buffer_.void_data()) Type();
  }

  static void Delete(Type* p) {
    if (p != NULL)
      p->Type::~Type();
  }

  static const bool kRegisterAtExit = true;
  static const bool kAllowedToAccessOnNonjoinableThread = true;

  // Exposed for unittesting.
  static void Resurrect() {
144
    butil::subtle::NoBarrier_Store(&dead_, 0);
gejun's avatar
gejun committed
145 146 147
  }

 private:
148
  static butil::AlignedMemory<sizeof(Type), ALIGNOF(Type)> buffer_;
gejun's avatar
gejun committed
149
  // Signal the object was already deleted, so it is not revived.
150
  static butil::subtle::Atomic32 dead_;
gejun's avatar
gejun committed
151 152
};

153
template <typename Type> butil::AlignedMemory<sizeof(Type), ALIGNOF(Type)>
gejun's avatar
gejun committed
154
    StaticMemorySingletonTraits<Type>::buffer_;
155
template <typename Type> butil::subtle::Atomic32
gejun's avatar
gejun committed
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
    StaticMemorySingletonTraits<Type>::dead_ = 0;

// The Singleton<Type, Traits, DifferentiatingType> class manages a single
// instance of Type which will be created on first use and will be destroyed at
// normal process exit). The Trait::Delete function will not be called on
// abnormal process exit.
//
// DifferentiatingType is used as a key to differentiate two different
// singletons having the same memory allocation functions but serving a
// different purpose. This is mainly used for Locks serving different purposes.
//
// Example usage:
//
// In your header:
//   template <typename T> struct DefaultSingletonTraits;
//   class FooClass {
//    public:
//     static FooClass* GetInstance();  <-- See comment below on this.
//     void Bar() { ... }
//    private:
//     FooClass() { ... }
//     friend struct DefaultSingletonTraits<FooClass>;
//
//     DISALLOW_COPY_AND_ASSIGN(FooClass);
//   };
//
// In your source file:
183
//  #include "butil/memory/singleton.h"
gejun's avatar
gejun committed
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
//  FooClass* FooClass::GetInstance() {
//    return Singleton<FooClass>::get();
//  }
//
// And to call methods on FooClass:
//   FooClass::GetInstance()->Bar();
//
// NOTE: The method accessing Singleton<T>::get() has to be named as GetInstance
// and it is important that FooClass::GetInstance() is not inlined in the
// header. This makes sure that when source files from multiple targets include
// this header they don't end up with different copies of the inlined code
// creating multiple copies of the singleton.
//
// Singleton<> has no non-static members and doesn't need to actually be
// instantiated.
//
// This class is itself thread-safe. The underlying Type must of course be
// thread-safe if you want to use it concurrently. Two parameters may be tuned
// depending on the user's requirements.
//
// Glossary:
//   RAE = kRegisterAtExit
//
// On every platform, if Traits::RAE is true, the singleton will be destroyed at
208
// process exit. More precisely it uses butil::AtExitManager which requires an
gejun's avatar
gejun committed
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245
// object of this type to be instantiated. AtExitManager mimics the semantics
// of atexit() such as LIFO order but under Windows is safer to call. For more
// information see at_exit.h.
//
// If Traits::RAE is false, the singleton will not be freed at process exit,
// thus the singleton will be leaked if it is ever accessed. Traits::RAE
// shouldn't be false unless absolutely necessary. Remember that the heap where
// the object is allocated may be destroyed by the CRT anyway.
//
// Caveats:
// (a) Every call to get(), operator->() and operator*() incurs some overhead
//     (16ns on my P4/2.8GHz) to check whether the object has already been
//     initialized.  You may wish to cache the result of get(); it will not
//     change.
//
// (b) Your factory function must never throw an exception. This class is not
//     exception-safe.
//
template <typename Type,
          typename Traits = DefaultSingletonTraits<Type>,
          typename DifferentiatingType = Type>
class Singleton {
 private:
  // Classes using the Singleton<T> pattern should declare a GetInstance()
  // method and call Singleton::get() from within that.
  friend Type* Type::GetInstance();

  // Allow TraceLog tests to test tracing after OnExit.
  friend class DeleteTraceLogForTesting;

  // This class is safe to be constructed and copy-constructed since it has no
  // member.

  // Return a pointer to the one true instance of the class.
  static Type* get() {
    // The load has acquire memory ordering as the thread which reads the
    // instance_ pointer must acquire visibility over the singleton data.
246 247
    butil::subtle::AtomicWord value = butil::subtle::Acquire_Load(&instance_);
    if (value != 0 && value != butil::internal::kBeingCreatedMarker) {
gejun's avatar
gejun committed
248 249 250 251 252 253
      // See the corresponding HAPPENS_BEFORE below.
      ANNOTATE_HAPPENS_AFTER(&instance_);
      return reinterpret_cast<Type*>(value);
    }

    // Object isn't created yet, maybe we will get to create it, let's try...
254 255
    if (butil::subtle::Acquire_CompareAndSwap(
          &instance_, 0, butil::internal::kBeingCreatedMarker) == 0) {
gejun's avatar
gejun committed
256 257 258 259 260 261 262 263 264 265
      // instance_ was NULL and is now kBeingCreatedMarker.  Only one thread
      // will ever get here.  Threads might be spinning on us, and they will
      // stop right after we do this store.
      Type* newval = Traits::New();

      // This annotation helps race detectors recognize correct lock-less
      // synchronization between different threads calling get().
      // See the corresponding HAPPENS_AFTER below and above.
      ANNOTATE_HAPPENS_BEFORE(&instance_);
      // Releases the visibility over instance_ to the readers.
266 267
      butil::subtle::Release_Store(
          &instance_, reinterpret_cast<butil::subtle::AtomicWord>(newval));
gejun's avatar
gejun committed
268 269

      if (newval != NULL && Traits::kRegisterAtExit)
270
        butil::AtExitManager::RegisterCallback(OnExit, NULL);
gejun's avatar
gejun committed
271 272 273 274 275

      return newval;
    }

    // We hit a race. Wait for the other thread to complete it.
276
    value = butil::internal::WaitForInstance(&instance_);
gejun's avatar
gejun committed
277 278 279 280 281 282 283 284 285 286 287 288 289

    // See the corresponding HAPPENS_BEFORE above.
    ANNOTATE_HAPPENS_AFTER(&instance_);
    return reinterpret_cast<Type*>(value);
  }

  // Adapter function for use with AtExit().  This should be called single
  // threaded, so don't use atomic operations.
  // Calling OnExit while singleton is in use by other threads is a mistake.
  static void OnExit(void* /*unused*/) {
    // AtExit should only ever be register after the singleton instance was
    // created.  We should only ever get here with a valid instance_ pointer.
    Traits::Delete(
290
        reinterpret_cast<Type*>(butil::subtle::NoBarrier_Load(&instance_)));
gejun's avatar
gejun committed
291 292
    instance_ = 0;
  }
293
  static butil::subtle::AtomicWord instance_;
gejun's avatar
gejun committed
294 295 296
};

template <typename Type, typename Traits, typename DifferentiatingType>
297
butil::subtle::AtomicWord Singleton<Type, Traits, DifferentiatingType>::
gejun's avatar
gejun committed
298 299
    instance_ = 0;

300
#endif  // BUTIL_MEMORY_SINGLETON_H_