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 |