OLD | NEW |
---|---|
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef BASE_SINGLETON_H_ | 5 #ifndef BASE_SINGLETON_H_ |
6 #define BASE_SINGLETON_H_ | 6 #define BASE_SINGLETON_H_ |
7 #pragma once | 7 #pragma once |
8 | 8 |
9 #include "base/at_exit.h" | 9 #include "base/at_exit.h" |
10 #include "base/atomicops.h" | 10 #include "base/atomicops.h" |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
107 | 107 |
108 // Signal the object was already deleted, so it is not revived. | 108 // Signal the object was already deleted, so it is not revived. |
109 static base::subtle::Atomic32 dead_; | 109 static base::subtle::Atomic32 dead_; |
110 }; | 110 }; |
111 | 111 |
112 template <typename Type> intptr_t | 112 template <typename Type> intptr_t |
113 StaticMemorySingletonTraits<Type>::buffer_[kBufferSize]; | 113 StaticMemorySingletonTraits<Type>::buffer_[kBufferSize]; |
114 template <typename Type> base::subtle::Atomic32 | 114 template <typename Type> base::subtle::Atomic32 |
115 StaticMemorySingletonTraits<Type>::dead_ = 0; | 115 StaticMemorySingletonTraits<Type>::dead_ = 0; |
116 | 116 |
117 // This is a hack to work around a limitation where a template argument cannot | |
118 // be declared as a friend directly. This is used in the below Singleton | |
119 // template. | |
120 template <typename T> | |
121 struct FriendMaker { | |
122 typedef T FriendType; | |
123 }; | |
117 | 124 |
118 // The Singleton<Type, Traits, DifferentiatingType> class manages a single | 125 // The Singleton<Type, Traits, DifferentiatingType> class manages a single |
119 // instance of Type which will be created on first use and will be destroyed at | 126 // instance of Type which will be created on first use and will be destroyed at |
120 // normal process exit). The Trait::Delete function will not be called on | 127 // normal process exit). The Trait::Delete function will not be called on |
121 // abnormal process exit. | 128 // abnormal process exit. |
122 // | 129 // |
123 // DifferentiatingType is used as a key to differentiate two different | 130 // DifferentiatingType is used as a key to differentiate two different |
124 // singletons having the same memory allocation functions but serving a | 131 // singletons having the same memory allocation functions but serving a |
125 // different purpose. This is mainly used for Locks serving different purposes. | 132 // different purpose. This is mainly used for Locks serving different purposes. |
126 // | 133 // |
127 // Example usages: (none are preferred, they all result in the same code) | 134 // Example usage: |
128 // 1. FooClass* ptr = Singleton<FooClass>::get(); | 135 // |
129 // ptr->Bar(); | 136 // In your header: |
130 // 2. Singleton<FooClass>()->Bar(); | 137 // #include "base/singleton.h" |
131 // 3. Singleton<FooClass>::get()->Bar(); | 138 // class FooClass { |
139 // public: | |
140 // static FooClass* GetInstance(); <-- See comment below on this. | |
141 // void Bar() { ... } | |
142 // private: | |
143 // FooClass() { ... } | |
144 // friend struct DefaultSingletonTraits<FooClass>; | |
145 // | |
146 // DISALLOW_COPY_AND_ASSIGN(FooClass); | |
147 // }; | |
148 // | |
149 // In your source file: | |
150 // FooClass* FooClass::GetInstance() { | |
151 // return Singleton<FooClass>::get(); | |
152 // } | |
153 // | |
154 // And to call methods on FooClass: | |
155 // FooClass::GetInstance()->Bar(); | |
156 // | |
157 // NOTE: It is important that FooClass::GetInstance() is not inlined in the | |
158 // header, so that when source files from multiple targets include this header | |
159 // they don't end up with different copies of the inlined code creating multiple | |
160 // copies of the singleton. | |
132 // | 161 // |
133 // Singleton<> has no non-static members and doesn't need to actually be | 162 // Singleton<> has no non-static members and doesn't need to actually be |
134 // instantiated. It does no harm to instantiate it and use it as a class member | 163 // instantiated. It does no harm to instantiate it and use it as a class member |
M-A Ruel
2010/12/10 14:52:18
Remove that too, we don't want to encourage multip
Satish
2010/12/10 17:13:48
Done.
| |
135 // or at global level since it is acting as a POD type. | 164 // since it is acting as a POD type. |
136 // | 165 // |
137 // This class is itself thread-safe. The underlying Type must of course be | 166 // This class is itself thread-safe. The underlying Type must of course be |
138 // thread-safe if you want to use it concurrently. Two parameters may be tuned | 167 // thread-safe if you want to use it concurrently. Two parameters may be tuned |
139 // depending on the user's requirements. | 168 // depending on the user's requirements. |
140 // | 169 // |
141 // Glossary: | 170 // Glossary: |
142 // RAE = kRegisterAtExit | 171 // RAE = kRegisterAtExit |
143 // | 172 // |
144 // On every platform, if Traits::RAE is true, the singleton will be destroyed at | 173 // On every platform, if Traits::RAE is true, the singleton will be destroyed at |
145 // process exit. More precisely it uses base::AtExitManager which requires an | 174 // process exit. More precisely it uses base::AtExitManager which requires an |
146 // object of this type to be instantiated. AtExitManager mimics the semantics | 175 // object of this type to be instantiated. AtExitManager mimics the semantics |
147 // of atexit() such as LIFO order but under Windows is safer to call. For more | 176 // of atexit() such as LIFO order but under Windows is safer to call. For more |
148 // information see at_exit.h. | 177 // information see at_exit.h. |
149 // | 178 // |
150 // If Traits::RAE is false, the singleton will not be freed at process exit, | 179 // If Traits::RAE is false, the singleton will not be freed at process exit, |
151 // thus the singleton will be leaked if it is ever accessed. Traits::RAE | 180 // thus the singleton will be leaked if it is ever accessed. Traits::RAE |
152 // shouldn't be false unless absolutely necessary. Remember that the heap where | 181 // shouldn't be false unless absolutely necessary. Remember that the heap where |
153 // the object is allocated may be destroyed by the CRT anyway. | 182 // the object is allocated may be destroyed by the CRT anyway. |
154 // | 183 // |
155 // If you want to ensure that your class can only exist as a singleton, make | |
156 // its constructors private, and make DefaultSingletonTraits<> a friend: | |
157 // | |
158 // #include "base/singleton.h" | |
159 // class FooClass { | |
160 // public: | |
161 // void Bar() { ... } | |
162 // private: | |
163 // FooClass() { ... } | |
164 // friend struct DefaultSingletonTraits<FooClass>; | |
165 // | |
166 // DISALLOW_COPY_AND_ASSIGN(FooClass); | |
167 // }; | |
168 // | |
169 // Caveats: | 184 // Caveats: |
170 // (a) Every call to get(), operator->() and operator*() incurs some overhead | 185 // (a) Every call to get(), operator->() and operator*() incurs some overhead |
171 // (16ns on my P4/2.8GHz) to check whether the object has already been | 186 // (16ns on my P4/2.8GHz) to check whether the object has already been |
172 // initialized. You may wish to cache the result of get(); it will not | 187 // initialized. You may wish to cache the result of get(); it will not |
173 // change. | 188 // change. |
174 // | 189 // |
175 // (b) Your factory function must never throw an exception. This class is not | 190 // (b) Your factory function must never throw an exception. This class is not |
176 // exception-safe. | 191 // exception-safe. |
177 // | 192 // |
178 template <typename Type, | 193 template <typename Type, |
179 typename Traits = DefaultSingletonTraits<Type>, | 194 typename Traits = DefaultSingletonTraits<Type>, |
180 typename DifferentiatingType = Type> | 195 typename DifferentiatingType = Type> |
181 class Singleton { | 196 class Singleton { |
182 public: | 197 private: |
198 #if defined(OS_WIN) | |
199 friend typename FriendMaker<Type>::FriendType; | |
M-A Ruel
2010/12/10 14:52:18
I think you don't need this utility class; try thi
Satish
2010/12/10 15:04:57
Doesn't work in GCC
"expected nested-name-specifie
M-A Ruel
2010/12/10 15:09:42
Try this instead.
typedef typename Type Type;
frie
Satish
2010/12/10 16:10:11
Yes I tried that too :) didn't work. I'll keep thi
| |
200 #else | |
201 friend class FriendMaker<Type>::FriendType; | |
202 #endif | |
203 | |
183 // This class is safe to be constructed and copy-constructed since it has no | 204 // This class is safe to be constructed and copy-constructed since it has no |
184 // member. | 205 // member. |
185 | 206 |
186 // Return a pointer to the one true instance of the class. | 207 // Return a pointer to the one true instance of the class. |
187 static Type* get() { | 208 static Type* get() { |
188 if (!Traits::kAllowedToAccessOnNonjoinableThread) | 209 if (!Traits::kAllowedToAccessOnNonjoinableThread) |
189 base::ThreadRestrictions::AssertSingletonAllowed(); | 210 base::ThreadRestrictions::AssertSingletonAllowed(); |
190 | 211 |
191 // Our AtomicWord doubles as a spinlock, where a value of | 212 // Our AtomicWord doubles as a spinlock, where a value of |
192 // kBeingCreatedMarker means the spinlock is being held for creation. | 213 // kBeingCreatedMarker means the spinlock is being held for creation. |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
233 if (value != kBeingCreatedMarker) | 254 if (value != kBeingCreatedMarker) |
234 break; | 255 break; |
235 PlatformThread::YieldCurrentThread(); | 256 PlatformThread::YieldCurrentThread(); |
236 } | 257 } |
237 | 258 |
238 // See the corresponding HAPPENS_BEFORE above. | 259 // See the corresponding HAPPENS_BEFORE above. |
239 ANNOTATE_HAPPENS_AFTER(&instance_); | 260 ANNOTATE_HAPPENS_AFTER(&instance_); |
240 return reinterpret_cast<Type*>(value); | 261 return reinterpret_cast<Type*>(value); |
241 } | 262 } |
242 | 263 |
243 // Shortcuts. | 264 // Shortcuts. |
M-A Ruel
2010/12/10 14:52:18
Probably time to remove these shortcuts. Maybe wor
Satish
2010/12/10 17:13:48
Done.
| |
244 Type& operator*() { | 265 Type& operator*() { |
245 return *get(); | 266 return *get(); |
246 } | 267 } |
247 | 268 |
248 Type* operator->() { | 269 Type* operator->() { |
249 return get(); | 270 return get(); |
250 } | 271 } |
251 | 272 |
252 private: | |
M-A Ruel
2010/12/10 14:52:18
Why make it public?
Satish
2010/12/10 17:13:48
This is still private, along with the rest of this
| |
253 // Adapter function for use with AtExit(). This should be called single | 273 // Adapter function for use with AtExit(). This should be called single |
254 // threaded, so don't use atomic operations. | 274 // threaded, so don't use atomic operations. |
255 // Calling OnExit while singleton is in use by other threads is a mistake. | 275 // Calling OnExit while singleton is in use by other threads is a mistake. |
256 static void OnExit(void* unused) { | 276 static void OnExit(void* unused) { |
257 // AtExit should only ever be register after the singleton instance was | 277 // AtExit should only ever be register after the singleton instance was |
258 // created. We should only ever get here with a valid instance_ pointer. | 278 // created. We should only ever get here with a valid instance_ pointer. |
259 Traits::Delete( | 279 Traits::Delete( |
260 reinterpret_cast<Type*>(base::subtle::NoBarrier_Load(&instance_))); | 280 reinterpret_cast<Type*>(base::subtle::NoBarrier_Load(&instance_))); |
261 instance_ = 0; | 281 instance_ = 0; |
262 } | 282 } |
263 static base::subtle::AtomicWord instance_; | 283 static base::subtle::AtomicWord instance_; |
264 }; | 284 }; |
265 | 285 |
266 template <typename Type, typename Traits, typename DifferentiatingType> | 286 template <typename Type, typename Traits, typename DifferentiatingType> |
267 base::subtle::AtomicWord Singleton<Type, Traits, DifferentiatingType>:: | 287 base::subtle::AtomicWord Singleton<Type, Traits, DifferentiatingType>:: |
268 instance_ = 0; | 288 instance_ = 0; |
269 | 289 |
270 #endif // BASE_SINGLETON_H_ | 290 #endif // BASE_SINGLETON_H_ |
OLD | NEW |