Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1033)

Side by Side Diff: base/memory/singleton.h

Issue 2932053002: Use C++11 alignment primitives (Closed)
Patch Set: Put back ALIGNAS Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 // PLEASE READ: Do you really need a singleton? 5 // PLEASE READ: Do you really need a singleton?
6 // 6 //
7 // Singletons make it hard to determine the lifetime of an object, which can 7 // Singletons make it hard to determine the lifetime of an object, which can
8 // lead to buggy code and spurious crashes. 8 // lead to buggy code and spurious crashes.
9 // 9 //
10 // Instead of adding another singleton into the mix, try to identify either: 10 // Instead of adding another singleton into the mix, try to identify either:
11 // a) An existing singleton that can manage your object's lifetime 11 // a) An existing singleton that can manage your object's lifetime
12 // b) Locations where you can deterministically create the object and pass 12 // b) Locations where you can deterministically create the object and pass
13 // into other objects 13 // into other objects
14 // 14 //
15 // If you absolutely need a singleton, please keep them as trivial as possible 15 // If you absolutely need a singleton, please keep them as trivial as possible
16 // and ideally a leaf dependency. Singletons get problematic when they attempt 16 // and ideally a leaf dependency. Singletons get problematic when they attempt
17 // to do too much in their destructor or have circular dependencies. 17 // to do too much in their destructor or have circular dependencies.
18 18
19 #ifndef BASE_MEMORY_SINGLETON_H_ 19 #ifndef BASE_MEMORY_SINGLETON_H_
20 #define BASE_MEMORY_SINGLETON_H_ 20 #define BASE_MEMORY_SINGLETON_H_
21 21
22 #include <type_traits>
23
22 #include "base/at_exit.h" 24 #include "base/at_exit.h"
23 #include "base/atomicops.h" 25 #include "base/atomicops.h"
24 #include "base/base_export.h" 26 #include "base/base_export.h"
25 #include "base/logging.h" 27 #include "base/logging.h"
26 #include "base/macros.h" 28 #include "base/macros.h"
27 #include "base/memory/aligned_memory.h"
28 #include "base/threading/thread_restrictions.h" 29 #include "base/threading/thread_restrictions.h"
29 30
30 namespace base { 31 namespace base {
31 namespace internal { 32 namespace internal {
32 33
33 // Our AtomicWord doubles as a spinlock, where a value of 34 // Our AtomicWord doubles as a spinlock, where a value of
34 // kBeingCreatedMarker means the spinlock is being held for creation. 35 // kBeingCreatedMarker means the spinlock is being held for creation.
35 static const subtle::AtomicWord kBeingCreatedMarker = 1; 36 static const subtle::AtomicWord kBeingCreatedMarker = 1;
36 37
37 // We pull out some of the functionality into a non-templated function, so that 38 // We pull out some of the functionality into a non-templated function, so that
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 // process once you've unloaded. 109 // process once you've unloaded.
109 template <typename Type> 110 template <typename Type>
110 struct StaticMemorySingletonTraits { 111 struct StaticMemorySingletonTraits {
111 // WARNING: User has to deal with get() in the singleton class 112 // WARNING: User has to deal with get() in the singleton class
112 // this is traits for returning NULL. 113 // this is traits for returning NULL.
113 static Type* New() { 114 static Type* New() {
114 // Only constructs once and returns pointer; otherwise returns NULL. 115 // Only constructs once and returns pointer; otherwise returns NULL.
115 if (subtle::NoBarrier_AtomicExchange(&dead_, 1)) 116 if (subtle::NoBarrier_AtomicExchange(&dead_, 1))
116 return NULL; 117 return NULL;
117 118
118 return new(buffer_.void_data()) Type(); 119 return new (&buffer_) Type();
119 } 120 }
120 121
121 static void Delete(Type* p) { 122 static void Delete(Type* p) {
122 if (p != NULL) 123 if (p != NULL)
123 p->Type::~Type(); 124 p->Type::~Type();
124 } 125 }
125 126
126 static const bool kRegisterAtExit = true; 127 static const bool kRegisterAtExit = true;
127 static const bool kAllowedToAccessOnNonjoinableThread = true; 128 static const bool kAllowedToAccessOnNonjoinableThread = true;
128 129
129 // Exposed for unittesting. 130 // Exposed for unittesting.
130 static void Resurrect() { subtle::NoBarrier_Store(&dead_, 0); } 131 static void Resurrect() { subtle::NoBarrier_Store(&dead_, 0); }
131 132
132 private: 133 private:
133 static AlignedMemory<sizeof(Type), ALIGNOF(Type)> buffer_; 134 static
135 typename std::aligned_storage<sizeof(Type), alignof(Type)>::type buffer_;
134 // Signal the object was already deleted, so it is not revived. 136 // Signal the object was already deleted, so it is not revived.
135 static subtle::Atomic32 dead_; 137 static subtle::Atomic32 dead_;
136 }; 138 };
137 139
138 template <typename Type> 140 template <typename Type>
139 AlignedMemory<sizeof(Type), ALIGNOF(Type)> 141 typename std::aligned_storage<sizeof(Type), alignof(Type)>::type
140 StaticMemorySingletonTraits<Type>::buffer_; 142 StaticMemorySingletonTraits<Type>::buffer_;
141 template <typename Type> 143 template <typename Type>
142 subtle::Atomic32 StaticMemorySingletonTraits<Type>::dead_ = 0; 144 subtle::Atomic32 StaticMemorySingletonTraits<Type>::dead_ = 0;
143 145
144 // The Singleton<Type, Traits, DifferentiatingType> class manages a single 146 // The Singleton<Type, Traits, DifferentiatingType> class manages a single
145 // instance of Type which will be created on first use and will be destroyed at 147 // instance of Type which will be created on first use and will be destroyed at
146 // normal process exit). The Trait::Delete function will not be called on 148 // normal process exit). The Trait::Delete function will not be called on
147 // abnormal process exit. 149 // abnormal process exit.
148 // 150 //
149 // DifferentiatingType is used as a key to differentiate two different 151 // DifferentiatingType is used as a key to differentiate two different
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 } 288 }
287 static subtle::AtomicWord instance_; 289 static subtle::AtomicWord instance_;
288 }; 290 };
289 291
290 template <typename Type, typename Traits, typename DifferentiatingType> 292 template <typename Type, typename Traits, typename DifferentiatingType>
291 subtle::AtomicWord Singleton<Type, Traits, DifferentiatingType>::instance_ = 0; 293 subtle::AtomicWord Singleton<Type, Traits, DifferentiatingType>::instance_ = 0;
292 294
293 } // namespace base 295 } // namespace base
294 296
295 #endif // BASE_MEMORY_SINGLETON_H_ 297 #endif // BASE_MEMORY_SINGLETON_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698