OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 // The LazyInstance<Type, Traits> class manages a single instance of Type, | 5 // The LazyInstance<Type, Traits> class manages a single instance of Type, |
6 // which will be lazily created on the first time it's accessed. This class is | 6 // which will be lazily created on the first time it's accessed. This class is |
7 // useful for places you would normally use a function-level static, but you | 7 // useful for places you would normally use a function-level static, but you |
8 // need to have guaranteed thread-safety. The Type constructor will only ever | 8 // need to have guaranteed thread-safety. The Type constructor will only ever |
9 // be called once, even if two threads are racing to create the object. Get() | 9 // be called once, even if two threads are racing to create the object. Get() |
10 // and Pointer() will always return the same, completely initialized instance. | 10 // and Pointer() will always return the same, completely initialized instance. |
(...skipping 23 matching lines...) Expand all Loading... |
34 | 34 |
35 #ifndef BASE_LAZY_INSTANCE_H_ | 35 #ifndef BASE_LAZY_INSTANCE_H_ |
36 #define BASE_LAZY_INSTANCE_H_ | 36 #define BASE_LAZY_INSTANCE_H_ |
37 #pragma once | 37 #pragma once |
38 | 38 |
39 #include <new> // For placement new. | 39 #include <new> // For placement new. |
40 | 40 |
41 #include "base/atomicops.h" | 41 #include "base/atomicops.h" |
42 #include "base/base_export.h" | 42 #include "base/base_export.h" |
43 #include "base/basictypes.h" | 43 #include "base/basictypes.h" |
| 44 #include "base/logging.h" |
44 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" | 45 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" |
45 #include "base/threading/thread_restrictions.h" | 46 #include "base/threading/thread_restrictions.h" |
46 | 47 |
47 namespace base { | 48 namespace base { |
48 | 49 |
49 template <typename Type> | 50 template <typename Type> |
50 struct DefaultLazyInstanceTraits { | 51 struct DefaultLazyInstanceTraits { |
51 static const bool kAllowedToAccessOnNonjoinableThread = false; | 52 static const bool kAllowedToAccessOnNonjoinableThread = false; |
52 | 53 |
53 static Type* New(void* instance) { | 54 static Type* New(void* instance) { |
| 55 DCHECK_EQ(reinterpret_cast<uintptr_t>(instance) % sizeof(instance), 0u) |
| 56 << ": Bad boy, the buffer passed to placement new is not aligned!\n" |
| 57 "This may break some stuff like SSE-based optimizations assuming the " |
| 58 "<Type> objects are word aligned."; |
54 // Use placement new to initialize our instance in our preallocated space. | 59 // Use placement new to initialize our instance in our preallocated space. |
55 // The parenthesis is very important here to force POD type initialization. | 60 // The parenthesis is very important here to force POD type initialization. |
56 return new (instance) Type(); | 61 return new (instance) Type(); |
57 } | 62 } |
58 static void Delete(void* instance) { | 63 static void Delete(void* instance) { |
59 // Explicitly call the destructor. | 64 // Explicitly call the destructor. |
60 reinterpret_cast<Type*>(instance)->~Type(); | 65 reinterpret_cast<Type*>(instance)->~Type(); |
61 } | 66 } |
62 }; | 67 }; |
63 | 68 |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
179 // threaded, so don't use atomic operations. | 184 // threaded, so don't use atomic operations. |
180 // Calling OnExit while the instance is in use by other threads is a mistake. | 185 // Calling OnExit while the instance is in use by other threads is a mistake. |
181 static void OnExit(void* lazy_instance) { | 186 static void OnExit(void* lazy_instance) { |
182 LazyInstance<Type, Traits>* me = | 187 LazyInstance<Type, Traits>* me = |
183 reinterpret_cast<LazyInstance<Type, Traits>*>(lazy_instance); | 188 reinterpret_cast<LazyInstance<Type, Traits>*>(lazy_instance); |
184 Traits::Delete(me->instance_); | 189 Traits::Delete(me->instance_); |
185 me->instance_ = NULL; | 190 me->instance_ = NULL; |
186 base::subtle::Release_Store(&me->state_, STATE_EMPTY); | 191 base::subtle::Release_Store(&me->state_, STATE_EMPTY); |
187 } | 192 } |
188 | 193 |
| 194 Type *instance_; |
189 int8 buf_[sizeof(Type)]; // Preallocate the space for the Type instance. | 195 int8 buf_[sizeof(Type)]; // Preallocate the space for the Type instance. |
190 Type *instance_; | |
191 | 196 |
192 DISALLOW_COPY_AND_ASSIGN(LazyInstance); | 197 DISALLOW_COPY_AND_ASSIGN(LazyInstance); |
193 }; | 198 }; |
194 | 199 |
195 } // namespace base | 200 } // namespace base |
196 | 201 |
197 #endif // BASE_LAZY_INSTANCE_H_ | 202 #endif // BASE_LAZY_INSTANCE_H_ |
OLD | NEW |