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) | |
Nico
2011/10/21 16:26:22
do you need this cast?
Timur Iskhodzhanov
2011/10/21 16:40:28
void * ptr;
ptr % const -> doesn't compile.
Sugge
| |
56 << ": Bad boy, the buffer is not aligned!"; | |
Nico
2011/10/21 16:26:22
Maybe explain why this is important and what to do
Timur Iskhodzhanov
2011/10/21 16:40:28
Why - Done.
What to do -> it shouldn't happen unle
| |
54 // Use placement new to initialize our instance in our preallocated space. | 57 // Use placement new to initialize our instance in our preallocated space. |
55 // The parenthesis is very important here to force POD type initialization. | 58 // The parenthesis is very important here to force POD type initialization. |
56 return new (instance) Type(); | 59 return new (instance) Type(); |
57 } | 60 } |
58 static void Delete(void* instance) { | 61 static void Delete(void* instance) { |
59 // Explicitly call the destructor. | 62 // Explicitly call the destructor. |
60 reinterpret_cast<Type*>(instance)->~Type(); | 63 reinterpret_cast<Type*>(instance)->~Type(); |
61 } | 64 } |
62 }; | 65 }; |
63 | 66 |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
179 // threaded, so don't use atomic operations. | 182 // threaded, so don't use atomic operations. |
180 // Calling OnExit while the instance is in use by other threads is a mistake. | 183 // Calling OnExit while the instance is in use by other threads is a mistake. |
181 static void OnExit(void* lazy_instance) { | 184 static void OnExit(void* lazy_instance) { |
182 LazyInstance<Type, Traits>* me = | 185 LazyInstance<Type, Traits>* me = |
183 reinterpret_cast<LazyInstance<Type, Traits>*>(lazy_instance); | 186 reinterpret_cast<LazyInstance<Type, Traits>*>(lazy_instance); |
184 Traits::Delete(me->instance_); | 187 Traits::Delete(me->instance_); |
185 me->instance_ = NULL; | 188 me->instance_ = NULL; |
186 base::subtle::Release_Store(&me->state_, STATE_EMPTY); | 189 base::subtle::Release_Store(&me->state_, STATE_EMPTY); |
187 } | 190 } |
188 | 191 |
192 Type *instance_; | |
189 int8 buf_[sizeof(Type)]; // Preallocate the space for the Type instance. | 193 int8 buf_[sizeof(Type)]; // Preallocate the space for the Type instance. |
190 Type *instance_; | |
191 | 194 |
192 DISALLOW_COPY_AND_ASSIGN(LazyInstance); | 195 DISALLOW_COPY_AND_ASSIGN(LazyInstance); |
193 }; | 196 }; |
194 | 197 |
195 } // namespace base | 198 } // namespace base |
196 | 199 |
197 #endif // BASE_LAZY_INSTANCE_H_ | 200 #endif // BASE_LAZY_INSTANCE_H_ |
OLD | NEW |