ipc/chromium/src/base/singleton.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/ipc/chromium/src/base/singleton.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,181 @@
     1.4 +// Copyright (c) 2006-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 +#ifndef BASE_SINGLETON_H_
     1.9 +#define BASE_SINGLETON_H_
    1.10 +
    1.11 +#include "base/at_exit.h"
    1.12 +#include "base/atomicops.h"
    1.13 +#include "base/platform_thread.h"
    1.14 +
    1.15 +// Default traits for Singleton<Type>. Calls operator new and operator delete on
    1.16 +// the object. Registers automatic deletion at process exit.
    1.17 +// Overload if you need arguments or another memory allocation function.
    1.18 +template<typename Type>
    1.19 +struct DefaultSingletonTraits {
    1.20 +  // Allocates the object.
    1.21 +  static Type* New() {
    1.22 +    // The parenthesis is very important here; it forces POD type
    1.23 +    // initialization.
    1.24 +    return new Type();
    1.25 +  }
    1.26 +
    1.27 +  // Destroys the object.
    1.28 +  static void Delete(Type* x) {
    1.29 +    delete x;
    1.30 +  }
    1.31 +
    1.32 +  // Set to true to automatically register deletion of the object on process
    1.33 +  // exit. See below for the required call that makes this happen.
    1.34 +  static const bool kRegisterAtExit = true;
    1.35 +};
    1.36 +
    1.37 +
    1.38 +// Alternate traits for use with the Singleton<Type>.  Identical to
    1.39 +// DefaultSingletonTraits except that the Singleton will not be cleaned up
    1.40 +// at exit.
    1.41 +template<typename Type>
    1.42 +struct LeakySingletonTraits : public DefaultSingletonTraits<Type> {
    1.43 +  static const bool kRegisterAtExit = false;
    1.44 +};
    1.45 +
    1.46 +
    1.47 +// The Singleton<Type, Traits, DifferentiatingType> class manages a single
    1.48 +// instance of Type which will be created on first use and will be destroyed at
    1.49 +// normal process exit). The Trait::Delete function will not be called on
    1.50 +// abnormal process exit.
    1.51 +//
    1.52 +// DifferentiatingType is used as a key to differentiate two different
    1.53 +// singletons having the same memory allocation functions but serving a
    1.54 +// different purpose. This is mainly used for Locks serving different purposes.
    1.55 +//
    1.56 +// Example usages: (none are preferred, they all result in the same code)
    1.57 +//   1. FooClass* ptr = Singleton<FooClass>::get();
    1.58 +//      ptr->Bar();
    1.59 +//   2. Singleton<FooClass>()->Bar();
    1.60 +//   3. Singleton<FooClass>::get()->Bar();
    1.61 +//
    1.62 +// Singleton<> has no non-static members and doesn't need to actually be
    1.63 +// instantiated. It does no harm to instantiate it and use it as a class member
    1.64 +// or at global level since it is acting as a POD type.
    1.65 +//
    1.66 +// This class is itself thread-safe. The underlying Type must of course be
    1.67 +// thread-safe if you want to use it concurrently. Two parameters may be tuned
    1.68 +// depending on the user's requirements.
    1.69 +//
    1.70 +// Glossary:
    1.71 +//   RAE = kRegisterAtExit
    1.72 +//
    1.73 +// On every platform, if Traits::RAE is true, the singleton will be destroyed at
    1.74 +// process exit. More precisely it uses base::AtExitManager which requires an
    1.75 +// object of this type to be instanciated. AtExitManager mimics the semantics
    1.76 +// of atexit() such as LIFO order but under Windows is safer to call. For more
    1.77 +// information see at_exit.h.
    1.78 +//
    1.79 +// If Traits::RAE is false, the singleton will not be freed at process exit,
    1.80 +// thus the singleton will be leaked if it is ever accessed. Traits::RAE
    1.81 +// shouldn't be false unless absolutely necessary. Remember that the heap where
    1.82 +// the object is allocated may be destroyed by the CRT anyway.
    1.83 +//
    1.84 +// If you want to ensure that your class can only exist as a singleton, make
    1.85 +// its constructors private, and make DefaultSingletonTraits<> a friend:
    1.86 +//
    1.87 +//   #include "base/singleton.h"
    1.88 +//   class FooClass {
    1.89 +//    public:
    1.90 +//     void Bar() { ... }
    1.91 +//    private:
    1.92 +//     FooClass() { ... }
    1.93 +//     friend struct DefaultSingletonTraits<FooClass>;
    1.94 +//
    1.95 +//     DISALLOW_EVIL_CONSTRUCTORS(FooClass);
    1.96 +//   };
    1.97 +//
    1.98 +// Caveats:
    1.99 +// (a) Every call to get(), operator->() and operator*() incurs some overhead
   1.100 +//     (16ns on my P4/2.8GHz) to check whether the object has already been
   1.101 +//     initialized.  You may wish to cache the result of get(); it will not
   1.102 +//     change.
   1.103 +//
   1.104 +// (b) Your factory function must never throw an exception. This class is not
   1.105 +//     exception-safe.
   1.106 +//
   1.107 +template <typename Type,
   1.108 +          typename Traits = DefaultSingletonTraits<Type>,
   1.109 +          typename DifferentiatingType = Type>
   1.110 +class Singleton {
   1.111 + public:
   1.112 +  // This class is safe to be constructed and copy-constructed since it has no
   1.113 +  // member.
   1.114 +
   1.115 +  // Return a pointer to the one true instance of the class.
   1.116 +  static Type* get() {
   1.117 +    // Our AtomicWord doubles as a spinlock, where a value of
   1.118 +    // kBeingCreatedMarker means the spinlock is being held for creation.
   1.119 +    static const base::subtle::AtomicWord kBeingCreatedMarker = 1;
   1.120 +
   1.121 +    base::subtle::AtomicWord value = base::subtle::NoBarrier_Load(&instance_);
   1.122 +    if (value != 0 && value != kBeingCreatedMarker)
   1.123 +      return reinterpret_cast<Type*>(value);
   1.124 +
   1.125 +    // Object isn't created yet, maybe we will get to create it, let's try...
   1.126 +    if (base::subtle::Acquire_CompareAndSwap(&instance_,
   1.127 +                                             0,
   1.128 +                                             kBeingCreatedMarker) == 0) {
   1.129 +      // instance_ was NULL and is now kBeingCreatedMarker.  Only one thread
   1.130 +      // will ever get here.  Threads might be spinning on us, and they will
   1.131 +      // stop right after we do this store.
   1.132 +      Type* newval = Traits::New();
   1.133 +      base::subtle::Release_Store(
   1.134 +          &instance_, reinterpret_cast<base::subtle::AtomicWord>(newval));
   1.135 +
   1.136 +      if (Traits::kRegisterAtExit)
   1.137 +        base::AtExitManager::RegisterCallback(OnExit, NULL);
   1.138 +
   1.139 +      return newval;
   1.140 +    }
   1.141 +
   1.142 +    // We hit a race.  Another thread beat us and either:
   1.143 +    // - Has the object in BeingCreated state
   1.144 +    // - Already has the object created...
   1.145 +    // We know value != NULL.  It could be kBeingCreatedMarker, or a valid ptr.
   1.146 +    // Unless your constructor can be very time consuming, it is very unlikely
   1.147 +    // to hit this race.  When it does, we just spin and yield the thread until
   1.148 +    // the object has been created.
   1.149 +    while (true) {
   1.150 +      value = base::subtle::NoBarrier_Load(&instance_);
   1.151 +      if (value != kBeingCreatedMarker)
   1.152 +        break;
   1.153 +      PlatformThread::YieldCurrentThread();
   1.154 +    }
   1.155 +
   1.156 +    return reinterpret_cast<Type*>(value);
   1.157 +  }
   1.158 +
   1.159 +  // Shortcuts.
   1.160 +  Type& operator*() {
   1.161 +    return *get();
   1.162 +  }
   1.163 +
   1.164 +  Type* operator->() {
   1.165 +    return get();
   1.166 +  }
   1.167 +
   1.168 + private:
   1.169 +  // Adapter function for use with AtExit().  This should be called single
   1.170 +  // threaded, but we might as well take the precautions anyway.
   1.171 +  static void OnExit(void* unused) {
   1.172 +    // AtExit should only ever be register after the singleton instance was
   1.173 +    // created.  We should only ever get here with a valid instance_ pointer.
   1.174 +    Traits::Delete(reinterpret_cast<Type*>(
   1.175 +        base::subtle::NoBarrier_AtomicExchange(&instance_, 0)));
   1.176 +  }
   1.177 +  static base::subtle::AtomicWord instance_;
   1.178 +};
   1.179 +
   1.180 +template <typename Type, typename Traits, typename DifferentiatingType>
   1.181 +base::subtle::AtomicWord Singleton<Type, Traits, DifferentiatingType>::
   1.182 +    instance_ = 0;
   1.183 +
   1.184 +#endif  // BASE_SINGLETON_H_

mercurial