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

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

Issue 2163023002: Unify usage of logging/assert macros in base/ (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix base/android/build_info.cc compile Created 4 years, 4 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/logging.h ('k') | base/message_loop/incoming_task_queue.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/macros.h" 26 #include "base/macros.h"
26 #include "base/memory/aligned_memory.h" 27 #include "base/memory/aligned_memory.h"
27 #include "base/threading/thread_restrictions.h" 28 #include "base/threading/thread_restrictions.h"
28 29
29 namespace base { 30 namespace base {
30 namespace internal { 31 namespace internal {
31 32
32 // Our AtomicWord doubles as a spinlock, where a value of 33 // Our AtomicWord doubles as a spinlock, where a value of
33 // kBeingCreatedMarker means the spinlock is being held for creation. 34 // kBeingCreatedMarker means the spinlock is being held for creation.
34 static const subtle::AtomicWord kBeingCreatedMarker = 1; 35 static const subtle::AtomicWord kBeingCreatedMarker = 1;
(...skipping 21 matching lines...) Expand all
56 57
57 // Destroys the object. 58 // Destroys the object.
58 static void Delete(Type* x) { 59 static void Delete(Type* x) {
59 delete x; 60 delete x;
60 } 61 }
61 62
62 // Set to true to automatically register deletion of the object on process 63 // Set to true to automatically register deletion of the object on process
63 // exit. See below for the required call that makes this happen. 64 // exit. See below for the required call that makes this happen.
64 static const bool kRegisterAtExit = true; 65 static const bool kRegisterAtExit = true;
65 66
66 #ifndef NDEBUG 67 #if DCHECK_IS_ON()
67 // Set to false to disallow access on a non-joinable thread. This is 68 // Set to false to disallow access on a non-joinable thread. This is
68 // different from kRegisterAtExit because StaticMemorySingletonTraits allows 69 // different from kRegisterAtExit because StaticMemorySingletonTraits allows
69 // access on non-joinable threads, and gracefully handles this. 70 // access on non-joinable threads, and gracefully handles this.
70 static const bool kAllowedToAccessOnNonjoinableThread = false; 71 static const bool kAllowedToAccessOnNonjoinableThread = false;
71 #endif 72 #endif
72 }; 73 };
73 74
74 75
75 // Alternate traits for use with the Singleton<Type>. Identical to 76 // Alternate traits for use with the Singleton<Type>. Identical to
76 // DefaultSingletonTraits except that the Singleton will not be cleaned up 77 // DefaultSingletonTraits except that the Singleton will not be cleaned up
77 // at exit. 78 // at exit.
78 template<typename Type> 79 template<typename Type>
79 struct LeakySingletonTraits : public DefaultSingletonTraits<Type> { 80 struct LeakySingletonTraits : public DefaultSingletonTraits<Type> {
80 static const bool kRegisterAtExit = false; 81 static const bool kRegisterAtExit = false;
81 #ifndef NDEBUG 82 #if DCHECK_IS_ON()
82 static const bool kAllowedToAccessOnNonjoinableThread = true; 83 static const bool kAllowedToAccessOnNonjoinableThread = true;
83 #endif 84 #endif
84 }; 85 };
85 86
86 87
87 // Alternate traits for use with the Singleton<Type>. Allocates memory 88 // Alternate traits for use with the Singleton<Type>. Allocates memory
88 // for the singleton instance from a static buffer. The singleton will 89 // for the singleton instance from a static buffer. The singleton will
89 // be cleaned up at exit, but can't be revived after destruction unless 90 // be cleaned up at exit, but can't be revived after destruction unless
90 // the Resurrect() method is called. 91 // the Resurrect() method is called.
91 // 92 //
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 friend Type* Type::GetInstance(); 221 friend Type* Type::GetInstance();
221 222
222 // Allow TraceLog tests to test tracing after OnExit. 223 // Allow TraceLog tests to test tracing after OnExit.
223 friend class internal::DeleteTraceLogForTesting; 224 friend class internal::DeleteTraceLogForTesting;
224 225
225 // This class is safe to be constructed and copy-constructed since it has no 226 // This class is safe to be constructed and copy-constructed since it has no
226 // member. 227 // member.
227 228
228 // Return a pointer to the one true instance of the class. 229 // Return a pointer to the one true instance of the class.
229 static Type* get() { 230 static Type* get() {
230 #ifndef NDEBUG 231 #if DCHECK_IS_ON()
231 // Avoid making TLS lookup on release builds. 232 // Avoid making TLS lookup on release builds.
232 if (!Traits::kAllowedToAccessOnNonjoinableThread) 233 if (!Traits::kAllowedToAccessOnNonjoinableThread)
233 ThreadRestrictions::AssertSingletonAllowed(); 234 ThreadRestrictions::AssertSingletonAllowed();
234 #endif 235 #endif
235 236
236 // The load has acquire memory ordering as the thread which reads the 237 // The load has acquire memory ordering as the thread which reads the
237 // instance_ pointer must acquire visibility over the singleton data. 238 // instance_ pointer must acquire visibility over the singleton data.
238 subtle::AtomicWord value = subtle::Acquire_Load(&instance_); 239 subtle::AtomicWord value = subtle::Acquire_Load(&instance_);
239 if (value != 0 && value != internal::kBeingCreatedMarker) { 240 if (value != 0 && value != internal::kBeingCreatedMarker) {
240 return reinterpret_cast<Type*>(value); 241 return reinterpret_cast<Type*>(value);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 } 276 }
276 static subtle::AtomicWord instance_; 277 static subtle::AtomicWord instance_;
277 }; 278 };
278 279
279 template <typename Type, typename Traits, typename DifferentiatingType> 280 template <typename Type, typename Traits, typename DifferentiatingType>
280 subtle::AtomicWord Singleton<Type, Traits, DifferentiatingType>::instance_ = 0; 281 subtle::AtomicWord Singleton<Type, Traits, DifferentiatingType>::instance_ = 0;
281 282
282 } // namespace base 283 } // namespace base
283 284
284 #endif // BASE_MEMORY_SINGLETON_H_ 285 #endif // BASE_MEMORY_SINGLETON_H_
OLDNEW
« no previous file with comments | « base/logging.h ('k') | base/message_loop/incoming_task_queue.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698