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