LCOV - code coverage report
Current view: top level - ipc/chromium/src/base - singleton.h (source / functions) Hit Total Coverage
Test: output.info Lines: 13 25 52.0 %
Date: 2017-07-14 16:53:18 Functions: 3 17 17.6 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13