xref: /aosp_15_r20/external/cronet/base/memory/singleton.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2011 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 //
5 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
6 // PLEASE READ: Do you really need a singleton? If possible, use a
7 // function-local static of type base::NoDestructor<T> instead:
8 //
9 // Factory& Factory::GetInstance() {
10 //   static base::NoDestructor<Factory> instance;
11 //   return *instance;
12 // }
13 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
14 //
15 // Singletons make it hard to determine the lifetime of an object, which can
16 // lead to buggy code and spurious crashes.
17 //
18 // Instead of adding another singleton into the mix, try to identify either:
19 //   a) An existing singleton that can manage your object's lifetime
20 //   b) Locations where you can deterministically create the object and pass
21 //      into other objects
22 //
23 // If you absolutely need a singleton, please keep them as trivial as possible
24 // and ideally a leaf dependency. Singletons get problematic when they attempt
25 // to do too much in their destructor or have circular dependencies.
26 
27 #ifndef BASE_MEMORY_SINGLETON_H_
28 #define BASE_MEMORY_SINGLETON_H_
29 
30 #include <atomic>
31 
32 #include "base/dcheck_is_on.h"
33 #include "base/lazy_instance_helpers.h"
34 #include "base/threading/thread_restrictions.h"
35 
36 namespace base {
37 
38 // Default traits for Singleton<Type>. Calls operator new and operator delete on
39 // the object. Registers automatic deletion at process exit.
40 // Overload if you need arguments or another memory allocation function.
41 template<typename Type>
42 struct DefaultSingletonTraits {
43   // Allocates the object.
NewDefaultSingletonTraits44   static Type* New() {
45     // The parenthesis is very important here; it forces POD type
46     // initialization.
47     return new Type();
48   }
49 
50   // Destroys the object.
DeleteDefaultSingletonTraits51   static void Delete(Type* x) {
52     delete x;
53   }
54 
55   // Set to true to automatically register deletion of the object on process
56   // exit. See below for the required call that makes this happen.
57   static const bool kRegisterAtExit = true;
58 
59 #if DCHECK_IS_ON()
60   // Set to false to disallow access on a non-joinable thread.  This is
61   // different from kRegisterAtExit because StaticMemorySingletonTraits allows
62   // access on non-joinable threads, and gracefully handles this.
63   static const bool kAllowedToAccessOnNonjoinableThread = false;
64 #endif
65 };
66 
67 
68 // Alternate traits for use with the Singleton<Type>.  Identical to
69 // DefaultSingletonTraits except that the Singleton will not be cleaned up
70 // at exit.
71 template<typename Type>
72 struct LeakySingletonTraits : public DefaultSingletonTraits<Type> {
73   static const bool kRegisterAtExit = false;
74 #if DCHECK_IS_ON()
75   static const bool kAllowedToAccessOnNonjoinableThread = true;
76 #endif
77 };
78 
79 // Alternate traits for use with the Singleton<Type>.  Allocates memory
80 // for the singleton instance from a static buffer.  The singleton will
81 // be cleaned up at exit, but can't be revived after destruction unless
82 // the ResurrectForTesting() method is called.
83 //
84 // This is useful for a certain category of things, notably logging and
85 // tracing, where the singleton instance is of a type carefully constructed to
86 // be safe to access post-destruction.
87 // In logging and tracing you'll typically get stray calls at odd times, like
88 // during static destruction, thread teardown and the like, and there's a
89 // termination race on the heap-based singleton - e.g. if one thread calls
90 // get(), but then another thread initiates AtExit processing, the first thread
91 // may call into an object residing in unallocated memory. If the instance is
92 // allocated from the data segment, then this is survivable.
93 //
94 // The destructor is to deallocate system resources, in this case to unregister
95 // a callback the system will invoke when logging levels change. Note that
96 // this is also used in e.g. Chrome Frame, where you have to allow for the
97 // possibility of loading briefly into someone else's process space, and
98 // so leaking is not an option, as that would sabotage the state of your host
99 // process once you've unloaded.
100 template <typename Type>
101 struct StaticMemorySingletonTraits {
102   // WARNING: User has to support a New() which returns null.
NewStaticMemorySingletonTraits103   static Type* New() {
104     // Only constructs once and returns pointer; otherwise returns null.
105     if (dead_.exchange(true, std::memory_order_relaxed))
106       return nullptr;
107 
108     return new (buffer_) Type();
109   }
110 
DeleteStaticMemorySingletonTraits111   static void Delete(Type* p) {
112     if (p)
113       p->Type::~Type();
114   }
115 
116   static const bool kRegisterAtExit = true;
117 
118 #if DCHECK_IS_ON()
119   static const bool kAllowedToAccessOnNonjoinableThread = true;
120 #endif
121 
ResurrectForTestingStaticMemorySingletonTraits122   static void ResurrectForTesting() {
123     dead_.store(false, std::memory_order_relaxed);
124   }
125 
126  private:
127   alignas(Type) static char buffer_[sizeof(Type)];
128   // Signal the object was already deleted, so it is not revived.
129   static std::atomic<bool> dead_;
130 };
131 
132 template <typename Type>
133 alignas(Type) char StaticMemorySingletonTraits<Type>::buffer_[sizeof(Type)];
134 template <typename Type>
135 std::atomic<bool> StaticMemorySingletonTraits<Type>::dead_ = false;
136 
137 // The Singleton<Type, Traits, DifferentiatingType> class manages a single
138 // instance of Type which will be created on first use and will be destroyed at
139 // normal process exit). The Trait::Delete function will not be called on
140 // abnormal process exit.
141 //
142 // DifferentiatingType is used as a key to differentiate two different
143 // singletons having the same memory allocation functions but serving a
144 // different purpose. This is mainly used for Locks serving different purposes.
145 //
146 // Example usage:
147 //
148 // In your header:
149 //   namespace base {
150 //   template <typename T>
151 //   struct DefaultSingletonTraits;
152 //   }
153 //   class FooClass {
154 //    public:
155 //     static FooClass* GetInstance();  <-- See comment below on this.
156 //
157 //     FooClass(const FooClass&) = delete;
158 //     FooClass& operator=(const FooClass&) = delete;
159 //
160 //     void Bar() { ... }
161 //
162 //    private:
163 //     FooClass() { ... }
164 //     friend struct base::DefaultSingletonTraits<FooClass>;
165 //   };
166 //
167 // In your source file:
168 //  #include "base/memory/singleton.h"
169 //  FooClass* FooClass::GetInstance() {
170 //    return base::Singleton<FooClass>::get();
171 //  }
172 //
173 // Or for leaky singletons:
174 //  #include "base/memory/singleton.h"
175 //  FooClass* FooClass::GetInstance() {
176 //    return base::Singleton<
177 //        FooClass, base::LeakySingletonTraits<FooClass>>::get();
178 //  }
179 //
180 // And to call methods on FooClass:
181 //   FooClass::GetInstance()->Bar();
182 //
183 // NOTE: The method accessing Singleton<T>::get() has to be named as GetInstance
184 // and it is important that FooClass::GetInstance() is not inlined in the
185 // header. This makes sure that when source files from multiple targets include
186 // this header they don't end up with different copies of the inlined code
187 // creating multiple copies of the singleton.
188 //
189 // Singleton<> has no non-static members and doesn't need to actually be
190 // instantiated.
191 //
192 // This class is itself thread-safe. The underlying Type must of course be
193 // thread-safe if you want to use it concurrently. Two parameters may be tuned
194 // depending on the user's requirements.
195 //
196 // Glossary:
197 //   RAE = kRegisterAtExit
198 //
199 // On every platform, if Traits::RAE is true, the singleton will be destroyed at
200 // process exit. More precisely it uses AtExitManager which requires an
201 // object of this type to be instantiated. AtExitManager mimics the semantics
202 // of atexit() such as LIFO order but under Windows is safer to call. For more
203 // information see at_exit.h.
204 //
205 // If Traits::RAE is false, the singleton will not be freed at process exit,
206 // thus the singleton will be leaked if it is ever accessed. Traits::RAE
207 // shouldn't be false unless absolutely necessary. Remember that the heap where
208 // the object is allocated may be destroyed by the CRT anyway.
209 //
210 // Caveats:
211 // (a) Every call to get(), operator->() and operator*() incurs some overhead
212 //     (16ns on my P4/2.8GHz) to check whether the object has already been
213 //     initialized.  You may wish to cache the result of get(); it will not
214 //     change.
215 //
216 // (b) Your factory function must never throw an exception. This class is not
217 //     exception-safe.
218 //
219 
220 template <typename Type,
221           typename Traits = DefaultSingletonTraits<Type>,
222           typename DifferentiatingType = Type>
223 class Singleton {
224  private:
225   // A class T using the Singleton<T> pattern should declare a GetInstance()
226   // method and call Singleton::get() from within that. T may also declare a
227   // GetInstanceIfExists() method to invoke Singleton::GetIfExists().
228   friend Type;
229 
230   // This class is safe to be constructed and copy-constructed since it has no
231   // member.
232 
233   // Returns a pointer to the one true instance of the class.
get()234   static Type* get() {
235 #if DCHECK_IS_ON()
236     if (!Traits::kAllowedToAccessOnNonjoinableThread)
237       internal::AssertSingletonAllowed();
238 #endif
239 
240     return subtle::GetOrCreateLazyPointer(
241         instance_, &CreatorFunc, nullptr,
242         Traits::kRegisterAtExit ? OnExit : nullptr, nullptr);
243   }
244 
245   // Returns the same result as get() if the instance exists but doesn't
246   // construct it (and returns null) if it doesn't.
GetIfExists()247   static Type* GetIfExists() {
248 #if DCHECK_IS_ON()
249     if (!Traits::kAllowedToAccessOnNonjoinableThread)
250       internal::AssertSingletonAllowed();
251 #endif
252 
253     if (!instance_.load(std::memory_order_relaxed))
254       return nullptr;
255 
256     // Need to invoke get() nonetheless as some Traits return null after
257     // destruction (even though |instance_| still holds garbage).
258     return get();
259   }
260 
261   // Internal method used as an adaptor for GetOrCreateLazyPointer(). Do not use
262   // outside of that use case.
CreatorFunc(void *)263   static Type* CreatorFunc(void* /* creator_arg*/) { return Traits::New(); }
264 
265   // Adapter function for use with AtExit().  This should be called single
266   // threaded, so don't use atomic operations.
267   // Calling OnExit while singleton is in use by other threads is a mistake.
OnExit(void *)268   static void OnExit(void* /*unused*/) {
269     // AtExit should only ever be register after the singleton instance was
270     // created.  We should only ever get here with a valid instance_ pointer.
271     Traits::Delete(
272         reinterpret_cast<Type*>(instance_.load(std::memory_order_relaxed)));
273     instance_.store(0, std::memory_order_relaxed);
274   }
275   static std::atomic<uintptr_t> instance_;
276 };
277 
278 template <typename Type, typename Traits, typename DifferentiatingType>
279 std::atomic<uintptr_t> Singleton<Type, Traits, DifferentiatingType>::instance_ =
280     0;
281 
282 }  // namespace base
283 
284 #endif  // BASE_MEMORY_SINGLETON_H_
285