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 | 7 |
8 #include "base/at_exit.h" | 8 #include "base/at_exit.h" |
9 #include "base/atomicops.h" | 9 #include "base/atomicops.h" |
| 10 #include "base/dynamic_annotations.h" |
10 #include "base/platform_thread.h" | 11 #include "base/platform_thread.h" |
11 | 12 |
12 // Default traits for Singleton<Type>. Calls operator new and operator delete on | 13 // Default traits for Singleton<Type>. Calls operator new and operator delete on |
13 // the object. Registers automatic deletion at process exit. | 14 // the object. Registers automatic deletion at process exit. |
14 // Overload if you need arguments or another memory allocation function. | 15 // Overload if you need arguments or another memory allocation function. |
15 template<typename Type> | 16 template<typename Type> |
16 struct DefaultSingletonTraits { | 17 struct DefaultSingletonTraits { |
17 // Allocates the object. | 18 // Allocates the object. |
18 static Type* New() { | 19 static Type* New() { |
19 // The parenthesis is very important here; it forces POD type | 20 // The parenthesis is very important here; it forces POD type |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
109 // This class is safe to be constructed and copy-constructed since it has no | 110 // This class is safe to be constructed and copy-constructed since it has no |
110 // member. | 111 // member. |
111 | 112 |
112 // Return a pointer to the one true instance of the class. | 113 // Return a pointer to the one true instance of the class. |
113 static Type* get() { | 114 static Type* get() { |
114 // Our AtomicWord doubles as a spinlock, where a value of | 115 // Our AtomicWord doubles as a spinlock, where a value of |
115 // kBeingCreatedMarker means the spinlock is being held for creation. | 116 // kBeingCreatedMarker means the spinlock is being held for creation. |
116 static const base::subtle::AtomicWord kBeingCreatedMarker = 1; | 117 static const base::subtle::AtomicWord kBeingCreatedMarker = 1; |
117 | 118 |
118 base::subtle::AtomicWord value = base::subtle::NoBarrier_Load(&instance_); | 119 base::subtle::AtomicWord value = base::subtle::NoBarrier_Load(&instance_); |
119 if (value != 0 && value != kBeingCreatedMarker) | 120 if (value != 0 && value != kBeingCreatedMarker) { |
| 121 // See the corresponding HAPPENS_BEFORE below. |
| 122 ANNOTATE_HAPPENS_AFTER(&instance_); |
120 return reinterpret_cast<Type*>(value); | 123 return reinterpret_cast<Type*>(value); |
| 124 } |
121 | 125 |
122 // Object isn't created yet, maybe we will get to create it, let's try... | 126 // Object isn't created yet, maybe we will get to create it, let's try... |
123 if (base::subtle::Acquire_CompareAndSwap(&instance_, | 127 if (base::subtle::Acquire_CompareAndSwap(&instance_, |
124 0, | 128 0, |
125 kBeingCreatedMarker) == 0) { | 129 kBeingCreatedMarker) == 0) { |
126 // instance_ was NULL and is now kBeingCreatedMarker. Only one thread | 130 // instance_ was NULL and is now kBeingCreatedMarker. Only one thread |
127 // will ever get here. Threads might be spinning on us, and they will | 131 // will ever get here. Threads might be spinning on us, and they will |
128 // stop right after we do this store. | 132 // stop right after we do this store. |
129 Type* newval = Traits::New(); | 133 Type* newval = Traits::New(); |
| 134 |
| 135 // This annotation helps race detectors recognize correct lock-less |
| 136 // synchronization between different threads calling get(). |
| 137 // See the corresponding HAPPENS_AFTER below and above. |
| 138 ANNOTATE_HAPPENS_BEFORE(&instance_); |
130 base::subtle::Release_Store( | 139 base::subtle::Release_Store( |
131 &instance_, reinterpret_cast<base::subtle::AtomicWord>(newval)); | 140 &instance_, reinterpret_cast<base::subtle::AtomicWord>(newval)); |
132 | 141 |
133 if (Traits::kRegisterAtExit) | 142 if (Traits::kRegisterAtExit) |
134 base::AtExitManager::RegisterCallback(OnExit, NULL); | 143 base::AtExitManager::RegisterCallback(OnExit, NULL); |
135 | 144 |
136 return newval; | 145 return newval; |
137 } | 146 } |
138 | 147 |
139 // We hit a race. Another thread beat us and either: | 148 // We hit a race. Another thread beat us and either: |
140 // - Has the object in BeingCreated state | 149 // - Has the object in BeingCreated state |
141 // - Already has the object created... | 150 // - Already has the object created... |
142 // We know value != NULL. It could be kBeingCreatedMarker, or a valid ptr. | 151 // We know value != NULL. It could be kBeingCreatedMarker, or a valid ptr. |
143 // Unless your constructor can be very time consuming, it is very unlikely | 152 // Unless your constructor can be very time consuming, it is very unlikely |
144 // to hit this race. When it does, we just spin and yield the thread until | 153 // to hit this race. When it does, we just spin and yield the thread until |
145 // the object has been created. | 154 // the object has been created. |
146 while (true) { | 155 while (true) { |
147 value = base::subtle::NoBarrier_Load(&instance_); | 156 value = base::subtle::NoBarrier_Load(&instance_); |
148 if (value != kBeingCreatedMarker) | 157 if (value != kBeingCreatedMarker) |
149 break; | 158 break; |
150 PlatformThread::YieldCurrentThread(); | 159 PlatformThread::YieldCurrentThread(); |
151 } | 160 } |
152 | 161 |
| 162 // See the corresponding HAPPENS_BEFORE above. |
| 163 ANNOTATE_HAPPENS_AFTER(&instance_); |
153 return reinterpret_cast<Type*>(value); | 164 return reinterpret_cast<Type*>(value); |
154 } | 165 } |
155 | 166 |
156 // Shortcuts. | 167 // Shortcuts. |
157 Type& operator*() { | 168 Type& operator*() { |
158 return *get(); | 169 return *get(); |
159 } | 170 } |
160 | 171 |
161 Type* operator->() { | 172 Type* operator->() { |
162 return get(); | 173 return get(); |
163 } | 174 } |
164 | 175 |
165 private: | 176 private: |
166 // Adapter function for use with AtExit(). This should be called single | 177 // Adapter function for use with AtExit(). This should be called single |
167 // threaded, but we might as well take the precautions anyway. | 178 // threaded, but we might as well take the precautions anyway. |
168 static void OnExit(void* unused) { | 179 static void OnExit(void* unused) { |
169 // AtExit should only ever be register after the singleton instance was | 180 // AtExit should only ever be register after the singleton instance was |
170 // created. We should only ever get here with a valid instance_ pointer. | 181 // created. We should only ever get here with a valid instance_ pointer. |
171 Traits::Delete(reinterpret_cast<Type*>( | 182 Traits::Delete(reinterpret_cast<Type*>( |
172 base::subtle::NoBarrier_AtomicExchange(&instance_, 0))); | 183 base::subtle::NoBarrier_AtomicExchange(&instance_, 0))); |
173 } | 184 } |
174 static base::subtle::AtomicWord instance_; | 185 static base::subtle::AtomicWord instance_; |
175 }; | 186 }; |
176 | 187 |
177 template <typename Type, typename Traits, typename DifferentiatingType> | 188 template <typename Type, typename Traits, typename DifferentiatingType> |
178 base::subtle::AtomicWord Singleton<Type, Traits, DifferentiatingType>:: | 189 base::subtle::AtomicWord Singleton<Type, Traits, DifferentiatingType>:: |
179 instance_ = 0; | 190 instance_ = 0; |
180 | 191 |
181 #endif // BASE_SINGLETON_H_ | 192 #endif // BASE_SINGLETON_H_ |
OLD | NEW |