LCOV - code coverage report
Current view: directory - ipc/chromium/src/base - singleton.h (source / functions) Found Hit Coverage
Test: app.info Lines: 24 12 50.0 %
Date: 2012-06-02 Functions: 25 5 20.0 %

       1                 : // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
       2                 : // Use of this source code is governed by a BSD-style license that can be
       3                 : // found in the LICENSE file.
       4                 : 
       5                 : #ifndef BASE_SINGLETON_H_
       6                 : #define BASE_SINGLETON_H_
       7                 : 
       8                 : #include "base/at_exit.h"
       9                 : #include "base/atomicops.h"
      10                 : #include "base/platform_thread.h"
      11                 : 
      12                 : // Default traits for Singleton<Type>. Calls operator new and operator delete on
      13                 : // the object. Registers automatic deletion at process exit.
      14                 : // Overload if you need arguments or another memory allocation function.
      15                 : template<typename Type>
      16                 : struct DefaultSingletonTraits {
      17                 :   // Allocates the object.
      18               2 :   static Type* New() {
      19                 :     // The parenthesis is very important here; it forces POD type
      20                 :     // initialization.
      21               2 :     return new Type();
      22                 :   }
      23                 : 
      24                 :   // Destroys the object.
      25               0 :   static void Delete(Type* x) {
      26               0 :     delete x;
      27               0 :   }
      28                 : 
      29                 :   // Set to true to automatically register deletion of the object on process
      30                 :   // exit. See below for the required call that makes this happen.
      31                 :   static const bool kRegisterAtExit = true;
      32                 : };
      33                 : 
      34                 : 
      35                 : // Alternate traits for use with the Singleton<Type>.  Identical to
      36                 : // DefaultSingletonTraits except that the Singleton will not be cleaned up
      37                 : // at exit.
      38                 : template<typename Type>
      39                 : struct LeakySingletonTraits : public DefaultSingletonTraits<Type> {
      40                 :   static const bool kRegisterAtExit = false;
      41                 : };
      42                 : 
      43                 : 
      44                 : // The Singleton<Type, Traits, DifferentiatingType> class manages a single
      45                 : // instance of Type which will be created on first use and will be destroyed at
      46                 : // normal process exit). The Trait::Delete function will not be called on
      47                 : // abnormal process exit.
      48                 : //
      49                 : // DifferentiatingType is used as a key to differentiate two different
      50                 : // singletons having the same memory allocation functions but serving a
      51                 : // different purpose. This is mainly used for Locks serving different purposes.
      52                 : //
      53                 : // Example usages: (none are preferred, they all result in the same code)
      54                 : //   1. FooClass* ptr = Singleton<FooClass>::get();
      55                 : //      ptr->Bar();
      56                 : //   2. Singleton<FooClass>()->Bar();
      57                 : //   3. Singleton<FooClass>::get()->Bar();
      58                 : //
      59                 : // Singleton<> has no non-static members and doesn't need to actually be
      60                 : // instantiated. It does no harm to instantiate it and use it as a class member
      61                 : // or at global level since it is acting as a POD type.
      62                 : //
      63                 : // This class is itself thread-safe. The underlying Type must of course be
      64                 : // thread-safe if you want to use it concurrently. Two parameters may be tuned
      65                 : // depending on the user's requirements.
      66                 : //
      67                 : // Glossary:
      68                 : //   RAE = kRegisterAtExit
      69                 : //
      70                 : // On every platform, if Traits::RAE is true, the singleton will be destroyed at
      71                 : // process exit. More precisely it uses base::AtExitManager which requires an
      72                 : // object of this type to be instanciated. AtExitManager mimics the semantics
      73                 : // of atexit() such as LIFO order but under Windows is safer to call. For more
      74                 : // information see at_exit.h.
      75                 : //
      76                 : // If Traits::RAE is false, the singleton will not be freed at process exit,
      77                 : // thus the singleton will be leaked if it is ever accessed. Traits::RAE
      78                 : // shouldn't be false unless absolutely necessary. Remember that the heap where
      79                 : // the object is allocated may be destroyed by the CRT anyway.
      80                 : //
      81                 : // If you want to ensure that your class can only exist as a singleton, make
      82                 : // its constructors private, and make DefaultSingletonTraits<> a friend:
      83                 : //
      84                 : //   #include "base/singleton.h"
      85                 : //   class FooClass {
      86                 : //    public:
      87                 : //     void Bar() { ... }
      88                 : //    private:
      89                 : //     FooClass() { ... }
      90                 : //     friend struct DefaultSingletonTraits<FooClass>;
      91                 : //
      92                 : //     DISALLOW_EVIL_CONSTRUCTORS(FooClass);
      93                 : //   };
      94                 : //
      95                 : // Caveats:
      96                 : // (a) Every call to get(), operator->() and operator*() incurs some overhead
      97                 : //     (16ns on my P4/2.8GHz) to check whether the object has already been
      98                 : //     initialized.  You may wish to cache the result of get(); it will not
      99                 : //     change.
     100                 : //
     101                 : // (b) Your factory function must never throw an exception. This class is not
     102                 : //     exception-safe.
     103                 : //
     104                 : template <typename Type,
     105                 :           typename Traits = DefaultSingletonTraits<Type>,
     106                 :           typename DifferentiatingType = Type>
     107                 : class Singleton {
     108                 :  public:
     109                 :   // This class is safe to be constructed and copy-constructed since it has no
     110                 :   // member.
     111                 : 
     112                 :   // Return a pointer to the one true instance of the class.
     113               2 :   static Type* get() {
     114                 :     // Our AtomicWord doubles as a spinlock, where a value of
     115                 :     // kBeingCreatedMarker means the spinlock is being held for creation.
     116                 :     static const base::subtle::AtomicWord kBeingCreatedMarker = 1;
     117                 : 
     118               2 :     base::subtle::AtomicWord value = base::subtle::NoBarrier_Load(&instance_);
     119               2 :     if (value != 0 && value != kBeingCreatedMarker)
     120               0 :       return reinterpret_cast<Type*>(value);
     121                 : 
     122                 :     // Object isn't created yet, maybe we will get to create it, let's try...
     123               2 :     if (base::subtle::Acquire_CompareAndSwap(&instance_,
     124                 :                                              0,
     125                 :                                              kBeingCreatedMarker) == 0) {
     126                 :       // instance_ was NULL and is now kBeingCreatedMarker.  Only one thread
     127                 :       // will ever get here.  Threads might be spinning on us, and they will
     128                 :       // stop right after we do this store.
     129               2 :       Type* newval = Traits::New();
     130               2 :       base::subtle::Release_Store(
     131                 :           &instance_, reinterpret_cast<base::subtle::AtomicWord>(newval));
     132                 : 
     133                 :       if (Traits::kRegisterAtExit)
     134               2 :         base::AtExitManager::RegisterCallback(OnExit, NULL);
     135                 : 
     136               2 :       return newval;
     137                 :     }
     138                 : 
     139                 :     // We hit a race.  Another thread beat us and either:
     140                 :     // - Has the object in BeingCreated state
     141                 :     // - Already has the object created...
     142                 :     // We know value != NULL.  It could be kBeingCreatedMarker, or a valid ptr.
     143                 :     // Unless your constructor can be very time consuming, it is very unlikely
     144                 :     // to hit this race.  When it does, we just spin and yield the thread until
     145                 :     // the object has been created.
     146               0 :     while (true) {
     147               0 :       value = base::subtle::NoBarrier_Load(&instance_);
     148               0 :       if (value != kBeingCreatedMarker)
     149                 :         break;
     150               0 :       PlatformThread::YieldCurrentThread();
     151                 :     }
     152                 : 
     153               0 :     return reinterpret_cast<Type*>(value);
     154                 :   }
     155                 : 
     156                 :   // Shortcuts.
     157                 :   Type& operator*() {
     158                 :     return *get();
     159                 :   }
     160                 : 
     161               1 :   Type* operator->() {
     162               1 :     return get();
     163                 :   }
     164                 : 
     165                 :  private:
     166                 :   // Adapter function for use with AtExit().  This should be called single
     167                 :   // threaded, but we might as well take the precautions anyway.
     168               0 :   static void OnExit(void* unused) {
     169                 :     // AtExit should only ever be register after the singleton instance was
     170                 :     // created.  We should only ever get here with a valid instance_ pointer.
     171               0 :     Traits::Delete(reinterpret_cast<Type*>(
     172                 :         base::subtle::NoBarrier_AtomicExchange(&instance_, 0)));
     173               0 :   }
     174                 :   static base::subtle::AtomicWord instance_;
     175                 : };
     176                 : 
     177                 : template <typename Type, typename Traits, typename DifferentiatingType>
     178                 : base::subtle::AtomicWord Singleton<Type, Traits, DifferentiatingType>::
     179                 :     instance_ = 0;
     180                 : 
     181                 : #endif  // BASE_SINGLETON_H_

Generated by: LCOV version 1.7