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

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

Issue 2932053002: Use C++11 alignment primitives (Closed)
Patch Set: Fix merge 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
« no previous file with comments | « base/memory/manual_constructor.h ('k') | base/memory/singleton_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "base/at_exit.h" 22 #include "base/at_exit.h"
23 #include "base/atomicops.h" 23 #include "base/atomicops.h"
24 #include "base/base_export.h" 24 #include "base/base_export.h"
25 #include "base/logging.h" 25 #include "base/logging.h"
26 #include "base/macros.h" 26 #include "base/macros.h"
27 #include "base/memory/aligned_memory.h"
28 #include "base/threading/thread_restrictions.h" 27 #include "base/threading/thread_restrictions.h"
29 28
30 namespace base { 29 namespace base {
31 namespace internal { 30 namespace internal {
32 31
33 // Our AtomicWord doubles as a spinlock, where a value of 32 // Our AtomicWord doubles as a spinlock, where a value of
34 // kBeingCreatedMarker means the spinlock is being held for creation. 33 // kBeingCreatedMarker means the spinlock is being held for creation.
35 static const subtle::AtomicWord kBeingCreatedMarker = 1; 34 static const subtle::AtomicWord kBeingCreatedMarker = 1;
36 35
37 // We pull out some of the functionality into a non-templated function, so that 36 // 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. 107 // process once you've unloaded.
109 template <typename Type> 108 template <typename Type>
110 struct StaticMemorySingletonTraits { 109 struct StaticMemorySingletonTraits {
111 // WARNING: User has to deal with get() in the singleton class 110 // WARNING: User has to deal with get() in the singleton class
112 // this is traits for returning NULL. 111 // this is traits for returning NULL.
113 static Type* New() { 112 static Type* New() {
114 // Only constructs once and returns pointer; otherwise returns NULL. 113 // Only constructs once and returns pointer; otherwise returns NULL.
115 if (subtle::NoBarrier_AtomicExchange(&dead_, 1)) 114 if (subtle::NoBarrier_AtomicExchange(&dead_, 1))
116 return NULL; 115 return NULL;
117 116
118 return new(buffer_.void_data()) Type(); 117 return new (buffer_) Type();
119 } 118 }
120 119
121 static void Delete(Type* p) { 120 static void Delete(Type* p) {
122 if (p != NULL) 121 if (p != NULL)
123 p->Type::~Type(); 122 p->Type::~Type();
124 } 123 }
125 124
126 static const bool kRegisterAtExit = true; 125 static const bool kRegisterAtExit = true;
127 static const bool kAllowedToAccessOnNonjoinableThread = true; 126 static const bool kAllowedToAccessOnNonjoinableThread = true;
128 127
129 // Exposed for unittesting. 128 // Exposed for unittesting.
130 static void Resurrect() { subtle::NoBarrier_Store(&dead_, 0); } 129 static void Resurrect() { subtle::NoBarrier_Store(&dead_, 0); }
131 130
132 private: 131 private:
133 static AlignedMemory<sizeof(Type), ALIGNOF(Type)> buffer_; 132 alignas(Type) static char buffer_[sizeof(Type)];
134 // Signal the object was already deleted, so it is not revived. 133 // Signal the object was already deleted, so it is not revived.
135 static subtle::Atomic32 dead_; 134 static subtle::Atomic32 dead_;
136 }; 135 };
137 136
138 template <typename Type> 137 template <typename Type>
139 AlignedMemory<sizeof(Type), ALIGNOF(Type)> 138 alignas(Type) char StaticMemorySingletonTraits<Type>::buffer_[sizeof(Type)];
140 StaticMemorySingletonTraits<Type>::buffer_;
141 template <typename Type> 139 template <typename Type>
142 subtle::Atomic32 StaticMemorySingletonTraits<Type>::dead_ = 0; 140 subtle::Atomic32 StaticMemorySingletonTraits<Type>::dead_ = 0;
143 141
144 // The Singleton<Type, Traits, DifferentiatingType> class manages a single 142 // 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 143 // 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 144 // normal process exit). The Trait::Delete function will not be called on
147 // abnormal process exit. 145 // abnormal process exit.
148 // 146 //
149 // DifferentiatingType is used as a key to differentiate two different 147 // DifferentiatingType is used as a key to differentiate two different
150 // singletons having the same memory allocation functions but serving a 148 // singletons having the same memory allocation functions but serving a
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 } 284 }
287 static subtle::AtomicWord instance_; 285 static subtle::AtomicWord instance_;
288 }; 286 };
289 287
290 template <typename Type, typename Traits, typename DifferentiatingType> 288 template <typename Type, typename Traits, typename DifferentiatingType>
291 subtle::AtomicWord Singleton<Type, Traits, DifferentiatingType>::instance_ = 0; 289 subtle::AtomicWord Singleton<Type, Traits, DifferentiatingType>::instance_ = 0;
292 290
293 } // namespace base 291 } // namespace base
294 292
295 #endif // BASE_MEMORY_SINGLETON_H_ 293 #endif // BASE_MEMORY_SINGLETON_H_
OLDNEW
« no previous file with comments | « base/memory/manual_constructor.h ('k') | base/memory/singleton_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698