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