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_
|