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" |
11 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" | 11 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" |
| 12 #include "base/thread_restrictions.h" |
12 | 13 |
13 // Default traits for Singleton<Type>. Calls operator new and operator delete on | 14 // Default traits for Singleton<Type>. Calls operator new and operator delete on |
14 // the object. Registers automatic deletion at process exit. | 15 // the object. Registers automatic deletion at process exit. |
15 // Overload if you need arguments or another memory allocation function. | 16 // Overload if you need arguments or another memory allocation function. |
16 template<typename Type> | 17 template<typename Type> |
17 struct DefaultSingletonTraits { | 18 struct DefaultSingletonTraits { |
18 // Allocates the object. | 19 // Allocates the object. |
19 static Type* New() { | 20 static Type* New() { |
20 // The parenthesis is very important here; it forces POD type | 21 // The parenthesis is very important here; it forces POD type |
21 // initialization. | 22 // initialization. |
22 return new Type(); | 23 return new Type(); |
23 } | 24 } |
24 | 25 |
25 // Destroys the object. | 26 // Destroys the object. |
26 static void Delete(Type* x) { | 27 static void Delete(Type* x) { |
27 delete x; | 28 delete x; |
28 } | 29 } |
29 | 30 |
30 // Set to true to automatically register deletion of the object on process | 31 // Set to true to automatically register deletion of the object on process |
31 // exit. See below for the required call that makes this happen. | 32 // exit. See below for the required call that makes this happen. |
32 static const bool kRegisterAtExit = true; | 33 static const bool kRegisterAtExit = true; |
| 34 |
| 35 // Set to false to disallow access on a non-joinable thread. This is |
| 36 // different from kRegisterAtExit because StaticMemorySingletonTraits allows |
| 37 // access on non-joinable threads, and gracefully handles this. |
| 38 static const bool kAllowedToAccessOnNonjoinableThread = false; |
33 }; | 39 }; |
34 | 40 |
35 | 41 |
36 // Alternate traits for use with the Singleton<Type>. Identical to | 42 // Alternate traits for use with the Singleton<Type>. Identical to |
37 // DefaultSingletonTraits except that the Singleton will not be cleaned up | 43 // DefaultSingletonTraits except that the Singleton will not be cleaned up |
38 // at exit. | 44 // at exit. |
39 template<typename Type> | 45 template<typename Type> |
40 struct LeakySingletonTraits : public DefaultSingletonTraits<Type> { | 46 struct LeakySingletonTraits : public DefaultSingletonTraits<Type> { |
41 static const bool kRegisterAtExit = false; | 47 static const bool kRegisterAtExit = false; |
| 48 static const bool kAllowedToAccessOnNonjoinableThread = true; |
42 }; | 49 }; |
43 | 50 |
44 | 51 |
45 // Alternate traits for use with the Singleton<Type>. Allocates memory | 52 // Alternate traits for use with the Singleton<Type>. Allocates memory |
46 // for the singleton instance from a static buffer. The singleton will | 53 // for the singleton instance from a static buffer. The singleton will |
47 // be cleaned up at exit, but can't be revived after destruction unless | 54 // be cleaned up at exit, but can't be revived after destruction unless |
48 // the Resurrect() method is called. | 55 // the Resurrect() method is called. |
49 // | 56 // |
50 // This is useful for a certain category of things, notably logging and | 57 // This is useful for a certain category of things, notably logging and |
51 // tracing, where the singleton instance is of a type carefully constructed to | 58 // tracing, where the singleton instance is of a type carefully constructed to |
(...skipping 26 matching lines...) Expand all Loading... |
78 } | 85 } |
79 | 86 |
80 static void Delete(Type* p) { | 87 static void Delete(Type* p) { |
81 base::subtle::NoBarrier_Store(&dead_, 1); | 88 base::subtle::NoBarrier_Store(&dead_, 1); |
82 base::subtle::MemoryBarrier(); | 89 base::subtle::MemoryBarrier(); |
83 if (p != NULL) | 90 if (p != NULL) |
84 p->Type::~Type(); | 91 p->Type::~Type(); |
85 } | 92 } |
86 | 93 |
87 static const bool kRegisterAtExit = true; | 94 static const bool kRegisterAtExit = true; |
| 95 static const bool kAllowedToAccessOnNonjoinableThread = true; |
88 | 96 |
89 // Exposed for unittesting. | 97 // Exposed for unittesting. |
90 static void Resurrect() { | 98 static void Resurrect() { |
91 base::subtle::NoBarrier_Store(&dead_, 0); | 99 base::subtle::NoBarrier_Store(&dead_, 0); |
92 } | 100 } |
93 | 101 |
94 private: | 102 private: |
95 static const size_t kBufferSize = (sizeof(Type) + | 103 static const size_t kBufferSize = (sizeof(Type) + |
96 sizeof(intptr_t) - 1) / sizeof(intptr_t); | 104 sizeof(intptr_t) - 1) / sizeof(intptr_t); |
97 static intptr_t buffer_[kBufferSize]; | 105 static intptr_t buffer_[kBufferSize]; |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 template <typename Type, | 177 template <typename Type, |
170 typename Traits = DefaultSingletonTraits<Type>, | 178 typename Traits = DefaultSingletonTraits<Type>, |
171 typename DifferentiatingType = Type> | 179 typename DifferentiatingType = Type> |
172 class Singleton { | 180 class Singleton { |
173 public: | 181 public: |
174 // This class is safe to be constructed and copy-constructed since it has no | 182 // This class is safe to be constructed and copy-constructed since it has no |
175 // member. | 183 // member. |
176 | 184 |
177 // Return a pointer to the one true instance of the class. | 185 // Return a pointer to the one true instance of the class. |
178 static Type* get() { | 186 static Type* get() { |
| 187 if (!Traits::kAllowedToAccessOnNonjoinableThread) |
| 188 base::ThreadRestrictions::AssertSingletonAllowed(); |
| 189 |
179 // Our AtomicWord doubles as a spinlock, where a value of | 190 // Our AtomicWord doubles as a spinlock, where a value of |
180 // kBeingCreatedMarker means the spinlock is being held for creation. | 191 // kBeingCreatedMarker means the spinlock is being held for creation. |
181 static const base::subtle::AtomicWord kBeingCreatedMarker = 1; | 192 static const base::subtle::AtomicWord kBeingCreatedMarker = 1; |
182 | 193 |
183 base::subtle::AtomicWord value = base::subtle::NoBarrier_Load(&instance_); | 194 base::subtle::AtomicWord value = base::subtle::NoBarrier_Load(&instance_); |
184 if (value != 0 && value != kBeingCreatedMarker) { | 195 if (value != 0 && value != kBeingCreatedMarker) { |
185 // See the corresponding HAPPENS_BEFORE below. | 196 // See the corresponding HAPPENS_BEFORE below. |
186 ANNOTATE_HAPPENS_AFTER(&instance_); | 197 ANNOTATE_HAPPENS_AFTER(&instance_); |
187 return reinterpret_cast<Type*>(value); | 198 return reinterpret_cast<Type*>(value); |
188 } | 199 } |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
249 instance_ = 0; | 260 instance_ = 0; |
250 } | 261 } |
251 static base::subtle::AtomicWord instance_; | 262 static base::subtle::AtomicWord instance_; |
252 }; | 263 }; |
253 | 264 |
254 template <typename Type, typename Traits, typename DifferentiatingType> | 265 template <typename Type, typename Traits, typename DifferentiatingType> |
255 base::subtle::AtomicWord Singleton<Type, Traits, DifferentiatingType>:: | 266 base::subtle::AtomicWord Singleton<Type, Traits, DifferentiatingType>:: |
256 instance_ = 0; | 267 instance_ = 0; |
257 | 268 |
258 #endif // BASE_SINGLETON_H_ | 269 #endif // BASE_SINGLETON_H_ |
OLD | NEW |