| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 | |
| 8 #include <stdlib.h> | |
| 9 | |
| 10 #include <utility> | |
| 11 | 7 |
| 12 #include "base/at_exit.h" | 8 #include "base/at_exit.h" |
| 13 #include "base/atomicops.h" | 9 #include "base/atomicops.h" |
| 14 #include "base/platform_thread.h" | 10 #include "base/platform_thread.h" |
| 15 | 11 |
| 16 // Default traits for Singleton<Type>. Calls operator new and operator delete on | 12 // Default traits for Singleton<Type>. Calls operator new and operator delete on |
| 17 // the object. Registers automatic deletion at process exit. | 13 // the object. Registers automatic deletion at process exit. |
| 18 // Overload if you need arguments or another memory allocation function. | 14 // Overload if you need arguments or another memory allocation function. |
| 19 template<typename Type> | 15 template<typename Type> |
| 20 struct DefaultSingletonTraits { | 16 struct DefaultSingletonTraits { |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 118 0, | 114 0, |
| 119 kBeingCreatedMarker) == 0) { | 115 kBeingCreatedMarker) == 0) { |
| 120 // instance_ was NULL and is now kBeingCreatedMarker. Only one thread | 116 // instance_ was NULL and is now kBeingCreatedMarker. Only one thread |
| 121 // will ever get here. Threads might be spinning on us, and they will | 117 // will ever get here. Threads might be spinning on us, and they will |
| 122 // stop right after we do this store. | 118 // stop right after we do this store. |
| 123 Type* newval = Traits::New(); | 119 Type* newval = Traits::New(); |
| 124 base::subtle::Release_Store( | 120 base::subtle::Release_Store( |
| 125 &instance_, reinterpret_cast<base::subtle::AtomicWord>(newval)); | 121 &instance_, reinterpret_cast<base::subtle::AtomicWord>(newval)); |
| 126 | 122 |
| 127 if (Traits::kRegisterAtExit) | 123 if (Traits::kRegisterAtExit) |
| 128 base::AtExitManager::RegisterCallback(OnExit); | 124 base::AtExitManager::RegisterCallback(OnExit, NULL); |
| 129 | 125 |
| 130 return newval; | 126 return newval; |
| 131 } | 127 } |
| 132 | 128 |
| 133 // We hit a race. Another thread beat us and either: | 129 // We hit a race. Another thread beat us and either: |
| 134 // - Has the object in BeingCreated state | 130 // - Has the object in BeingCreated state |
| 135 // - Already has the object created... | 131 // - Already has the object created... |
| 136 // We know value != NULL. It could be kBeingCreatedMarker, or a valid ptr. | 132 // We know value != NULL. It could be kBeingCreatedMarker, or a valid ptr. |
| 137 // Unless your constructor can be very time consuming, it is very unlikely | 133 // Unless your constructor can be very time consuming, it is very unlikely |
| 138 // to hit this race. When it does, we just spin and yield the thread until | 134 // to hit this race. When it does, we just spin and yield the thread until |
| (...skipping 13 matching lines...) Expand all Loading... |
| 152 return *get(); | 148 return *get(); |
| 153 } | 149 } |
| 154 | 150 |
| 155 Type* operator->() { | 151 Type* operator->() { |
| 156 return get(); | 152 return get(); |
| 157 } | 153 } |
| 158 | 154 |
| 159 private: | 155 private: |
| 160 // Adapter function for use with AtExit(). This should be called single | 156 // Adapter function for use with AtExit(). This should be called single |
| 161 // threaded, but we might as well take the precautions anyway. | 157 // threaded, but we might as well take the precautions anyway. |
| 162 static void OnExit() { | 158 static void OnExit(void* unused) { |
| 163 // AtExit should only ever be register after the singleton instance was | 159 // AtExit should only ever be register after the singleton instance was |
| 164 // created. We should only ever get here with a valid instance_ pointer. | 160 // created. We should only ever get here with a valid instance_ pointer. |
| 165 Traits::Delete(reinterpret_cast<Type*>( | 161 Traits::Delete(reinterpret_cast<Type*>( |
| 166 base::subtle::NoBarrier_AtomicExchange(&instance_, 0))); | 162 base::subtle::NoBarrier_AtomicExchange(&instance_, 0))); |
| 167 } | 163 } |
| 168 static base::subtle::AtomicWord instance_; | 164 static base::subtle::AtomicWord instance_; |
| 169 }; | 165 }; |
| 170 | 166 |
| 171 template <typename Type, typename Traits, typename DifferentiatingType> | 167 template <typename Type, typename Traits, typename DifferentiatingType> |
| 172 base::subtle::AtomicWord Singleton<Type, Traits, DifferentiatingType>:: | 168 base::subtle::AtomicWord Singleton<Type, Traits, DifferentiatingType>:: |
| 173 instance_ = 0; | 169 instance_ = 0; |
| 174 | 170 |
| 175 | 171 #endif // BASE_SINGLETON_H_ |
| 176 #endif // BASE_SINGLETON_H__ | |
| 177 | |
| OLD | NEW |