xref: /aosp_15_r20/external/libchrome/base/memory/ref_counted.h (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2012 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 #ifndef BASE_MEMORY_REF_COUNTED_H_
6*635a8641SAndroid Build Coastguard Worker #define BASE_MEMORY_REF_COUNTED_H_
7*635a8641SAndroid Build Coastguard Worker 
8*635a8641SAndroid Build Coastguard Worker #include <stddef.h>
9*635a8641SAndroid Build Coastguard Worker 
10*635a8641SAndroid Build Coastguard Worker #include <utility>
11*635a8641SAndroid Build Coastguard Worker 
12*635a8641SAndroid Build Coastguard Worker #include "base/atomic_ref_count.h"
13*635a8641SAndroid Build Coastguard Worker #include "base/base_export.h"
14*635a8641SAndroid Build Coastguard Worker #include "base/compiler_specific.h"
15*635a8641SAndroid Build Coastguard Worker #include "base/logging.h"
16*635a8641SAndroid Build Coastguard Worker #include "base/macros.h"
17*635a8641SAndroid Build Coastguard Worker #include "base/memory/scoped_refptr.h"
18*635a8641SAndroid Build Coastguard Worker #include "base/sequence_checker.h"
19*635a8641SAndroid Build Coastguard Worker #include "base/threading/thread_collision_warner.h"
20*635a8641SAndroid Build Coastguard Worker #include "build/build_config.h"
21*635a8641SAndroid Build Coastguard Worker 
22*635a8641SAndroid Build Coastguard Worker namespace base {
23*635a8641SAndroid Build Coastguard Worker namespace subtle {
24*635a8641SAndroid Build Coastguard Worker 
25*635a8641SAndroid Build Coastguard Worker class BASE_EXPORT RefCountedBase {
26*635a8641SAndroid Build Coastguard Worker  public:
HasOneRef()27*635a8641SAndroid Build Coastguard Worker   bool HasOneRef() const { return ref_count_ == 1; }
28*635a8641SAndroid Build Coastguard Worker 
29*635a8641SAndroid Build Coastguard Worker  protected:
RefCountedBase(StartRefCountFromZeroTag)30*635a8641SAndroid Build Coastguard Worker   explicit RefCountedBase(StartRefCountFromZeroTag) {
31*635a8641SAndroid Build Coastguard Worker #if DCHECK_IS_ON()
32*635a8641SAndroid Build Coastguard Worker     sequence_checker_.DetachFromSequence();
33*635a8641SAndroid Build Coastguard Worker #endif
34*635a8641SAndroid Build Coastguard Worker   }
35*635a8641SAndroid Build Coastguard Worker 
RefCountedBase(StartRefCountFromOneTag)36*635a8641SAndroid Build Coastguard Worker   explicit RefCountedBase(StartRefCountFromOneTag) : ref_count_(1) {
37*635a8641SAndroid Build Coastguard Worker #if DCHECK_IS_ON()
38*635a8641SAndroid Build Coastguard Worker     needs_adopt_ref_ = true;
39*635a8641SAndroid Build Coastguard Worker     sequence_checker_.DetachFromSequence();
40*635a8641SAndroid Build Coastguard Worker #endif
41*635a8641SAndroid Build Coastguard Worker   }
42*635a8641SAndroid Build Coastguard Worker 
~RefCountedBase()43*635a8641SAndroid Build Coastguard Worker   ~RefCountedBase() {
44*635a8641SAndroid Build Coastguard Worker #if DCHECK_IS_ON()
45*635a8641SAndroid Build Coastguard Worker     DCHECK(in_dtor_) << "RefCounted object deleted without calling Release()";
46*635a8641SAndroid Build Coastguard Worker #endif
47*635a8641SAndroid Build Coastguard Worker   }
48*635a8641SAndroid Build Coastguard Worker 
AddRef()49*635a8641SAndroid Build Coastguard Worker   void AddRef() const {
50*635a8641SAndroid Build Coastguard Worker     // TODO(maruel): Add back once it doesn't assert 500 times/sec.
51*635a8641SAndroid Build Coastguard Worker     // Current thread books the critical section "AddRelease"
52*635a8641SAndroid Build Coastguard Worker     // without release it.
53*635a8641SAndroid Build Coastguard Worker     // DFAKE_SCOPED_LOCK_THREAD_LOCKED(add_release_);
54*635a8641SAndroid Build Coastguard Worker #if DCHECK_IS_ON()
55*635a8641SAndroid Build Coastguard Worker     DCHECK(!in_dtor_);
56*635a8641SAndroid Build Coastguard Worker     DCHECK(!needs_adopt_ref_)
57*635a8641SAndroid Build Coastguard Worker         << "This RefCounted object is created with non-zero reference count."
58*635a8641SAndroid Build Coastguard Worker         << " The first reference to such a object has to be made by AdoptRef or"
59*635a8641SAndroid Build Coastguard Worker         << " MakeRefCounted.";
60*635a8641SAndroid Build Coastguard Worker     if (ref_count_ >= 1) {
61*635a8641SAndroid Build Coastguard Worker       DCHECK(CalledOnValidSequence());
62*635a8641SAndroid Build Coastguard Worker     }
63*635a8641SAndroid Build Coastguard Worker #endif
64*635a8641SAndroid Build Coastguard Worker 
65*635a8641SAndroid Build Coastguard Worker     AddRefImpl();
66*635a8641SAndroid Build Coastguard Worker   }
67*635a8641SAndroid Build Coastguard Worker 
68*635a8641SAndroid Build Coastguard Worker   // Returns true if the object should self-delete.
Release()69*635a8641SAndroid Build Coastguard Worker   bool Release() const {
70*635a8641SAndroid Build Coastguard Worker     --ref_count_;
71*635a8641SAndroid Build Coastguard Worker 
72*635a8641SAndroid Build Coastguard Worker     // TODO(maruel): Add back once it doesn't assert 500 times/sec.
73*635a8641SAndroid Build Coastguard Worker     // Current thread books the critical section "AddRelease"
74*635a8641SAndroid Build Coastguard Worker     // without release it.
75*635a8641SAndroid Build Coastguard Worker     // DFAKE_SCOPED_LOCK_THREAD_LOCKED(add_release_);
76*635a8641SAndroid Build Coastguard Worker 
77*635a8641SAndroid Build Coastguard Worker #if DCHECK_IS_ON()
78*635a8641SAndroid Build Coastguard Worker     DCHECK(!in_dtor_);
79*635a8641SAndroid Build Coastguard Worker     if (ref_count_ == 0)
80*635a8641SAndroid Build Coastguard Worker       in_dtor_ = true;
81*635a8641SAndroid Build Coastguard Worker 
82*635a8641SAndroid Build Coastguard Worker     if (ref_count_ >= 1)
83*635a8641SAndroid Build Coastguard Worker       DCHECK(CalledOnValidSequence());
84*635a8641SAndroid Build Coastguard Worker     if (ref_count_ == 1)
85*635a8641SAndroid Build Coastguard Worker       sequence_checker_.DetachFromSequence();
86*635a8641SAndroid Build Coastguard Worker #endif
87*635a8641SAndroid Build Coastguard Worker 
88*635a8641SAndroid Build Coastguard Worker     return ref_count_ == 0;
89*635a8641SAndroid Build Coastguard Worker   }
90*635a8641SAndroid Build Coastguard Worker 
91*635a8641SAndroid Build Coastguard Worker   // Returns true if it is safe to read or write the object, from a thread
92*635a8641SAndroid Build Coastguard Worker   // safety standpoint. Should be DCHECK'd from the methods of RefCounted
93*635a8641SAndroid Build Coastguard Worker   // classes if there is a danger of objects being shared across threads.
94*635a8641SAndroid Build Coastguard Worker   //
95*635a8641SAndroid Build Coastguard Worker   // This produces fewer false positives than adding a separate SequenceChecker
96*635a8641SAndroid Build Coastguard Worker   // into the subclass, because it automatically detaches from the sequence when
97*635a8641SAndroid Build Coastguard Worker   // the reference count is 1 (and never fails if there is only one reference).
98*635a8641SAndroid Build Coastguard Worker   //
99*635a8641SAndroid Build Coastguard Worker   // This means unlike a separate SequenceChecker, it will permit a singly
100*635a8641SAndroid Build Coastguard Worker   // referenced object to be passed between threads (not holding a reference on
101*635a8641SAndroid Build Coastguard Worker   // the sending thread), but will trap if the sending thread holds onto a
102*635a8641SAndroid Build Coastguard Worker   // reference, or if the object is accessed from multiple threads
103*635a8641SAndroid Build Coastguard Worker   // simultaneously.
IsOnValidSequence()104*635a8641SAndroid Build Coastguard Worker   bool IsOnValidSequence() const {
105*635a8641SAndroid Build Coastguard Worker #if DCHECK_IS_ON()
106*635a8641SAndroid Build Coastguard Worker     return ref_count_ <= 1 || CalledOnValidSequence();
107*635a8641SAndroid Build Coastguard Worker #else
108*635a8641SAndroid Build Coastguard Worker     return true;
109*635a8641SAndroid Build Coastguard Worker #endif
110*635a8641SAndroid Build Coastguard Worker   }
111*635a8641SAndroid Build Coastguard Worker 
112*635a8641SAndroid Build Coastguard Worker  private:
113*635a8641SAndroid Build Coastguard Worker   template <typename U>
114*635a8641SAndroid Build Coastguard Worker   friend scoped_refptr<U> base::AdoptRef(U*);
115*635a8641SAndroid Build Coastguard Worker 
Adopted()116*635a8641SAndroid Build Coastguard Worker   void Adopted() const {
117*635a8641SAndroid Build Coastguard Worker #if DCHECK_IS_ON()
118*635a8641SAndroid Build Coastguard Worker     DCHECK(needs_adopt_ref_);
119*635a8641SAndroid Build Coastguard Worker     needs_adopt_ref_ = false;
120*635a8641SAndroid Build Coastguard Worker #endif
121*635a8641SAndroid Build Coastguard Worker   }
122*635a8641SAndroid Build Coastguard Worker 
123*635a8641SAndroid Build Coastguard Worker #if defined(ARCH_CPU_64_BIT)
124*635a8641SAndroid Build Coastguard Worker   void AddRefImpl() const;
125*635a8641SAndroid Build Coastguard Worker #else
AddRefImpl()126*635a8641SAndroid Build Coastguard Worker   void AddRefImpl() const { ++ref_count_; }
127*635a8641SAndroid Build Coastguard Worker #endif
128*635a8641SAndroid Build Coastguard Worker 
129*635a8641SAndroid Build Coastguard Worker #if DCHECK_IS_ON()
130*635a8641SAndroid Build Coastguard Worker   bool CalledOnValidSequence() const;
131*635a8641SAndroid Build Coastguard Worker #endif
132*635a8641SAndroid Build Coastguard Worker 
133*635a8641SAndroid Build Coastguard Worker   mutable uint32_t ref_count_ = 0;
134*635a8641SAndroid Build Coastguard Worker 
135*635a8641SAndroid Build Coastguard Worker #if DCHECK_IS_ON()
136*635a8641SAndroid Build Coastguard Worker   mutable bool needs_adopt_ref_ = false;
137*635a8641SAndroid Build Coastguard Worker   mutable bool in_dtor_ = false;
138*635a8641SAndroid Build Coastguard Worker   mutable SequenceChecker sequence_checker_;
139*635a8641SAndroid Build Coastguard Worker #endif
140*635a8641SAndroid Build Coastguard Worker 
141*635a8641SAndroid Build Coastguard Worker   DFAKE_MUTEX(add_release_);
142*635a8641SAndroid Build Coastguard Worker 
143*635a8641SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(RefCountedBase);
144*635a8641SAndroid Build Coastguard Worker };
145*635a8641SAndroid Build Coastguard Worker 
146*635a8641SAndroid Build Coastguard Worker class BASE_EXPORT RefCountedThreadSafeBase {
147*635a8641SAndroid Build Coastguard Worker  public:
148*635a8641SAndroid Build Coastguard Worker   bool HasOneRef() const;
149*635a8641SAndroid Build Coastguard Worker 
150*635a8641SAndroid Build Coastguard Worker  protected:
RefCountedThreadSafeBase(StartRefCountFromZeroTag)151*635a8641SAndroid Build Coastguard Worker   explicit constexpr RefCountedThreadSafeBase(StartRefCountFromZeroTag) {}
RefCountedThreadSafeBase(StartRefCountFromOneTag)152*635a8641SAndroid Build Coastguard Worker   explicit constexpr RefCountedThreadSafeBase(StartRefCountFromOneTag)
153*635a8641SAndroid Build Coastguard Worker       : ref_count_(1) {
154*635a8641SAndroid Build Coastguard Worker #if DCHECK_IS_ON()
155*635a8641SAndroid Build Coastguard Worker     needs_adopt_ref_ = true;
156*635a8641SAndroid Build Coastguard Worker #endif
157*635a8641SAndroid Build Coastguard Worker   }
158*635a8641SAndroid Build Coastguard Worker 
159*635a8641SAndroid Build Coastguard Worker #if DCHECK_IS_ON()
160*635a8641SAndroid Build Coastguard Worker   ~RefCountedThreadSafeBase();
161*635a8641SAndroid Build Coastguard Worker #else
162*635a8641SAndroid Build Coastguard Worker   ~RefCountedThreadSafeBase() = default;
163*635a8641SAndroid Build Coastguard Worker #endif
164*635a8641SAndroid Build Coastguard Worker 
165*635a8641SAndroid Build Coastguard Worker // Release and AddRef are suitable for inlining on X86 because they generate
166*635a8641SAndroid Build Coastguard Worker // very small code sequences. On other platforms (ARM), it causes a size
167*635a8641SAndroid Build Coastguard Worker // regression and is probably not worth it.
168*635a8641SAndroid Build Coastguard Worker #if defined(ARCH_CPU_X86_FAMILY)
169*635a8641SAndroid Build Coastguard Worker   // Returns true if the object should self-delete.
Release()170*635a8641SAndroid Build Coastguard Worker   bool Release() const { return ReleaseImpl(); }
AddRef()171*635a8641SAndroid Build Coastguard Worker   void AddRef() const { AddRefImpl(); }
172*635a8641SAndroid Build Coastguard Worker #else
173*635a8641SAndroid Build Coastguard Worker   // Returns true if the object should self-delete.
174*635a8641SAndroid Build Coastguard Worker   bool Release() const;
175*635a8641SAndroid Build Coastguard Worker   void AddRef() const;
176*635a8641SAndroid Build Coastguard Worker #endif
177*635a8641SAndroid Build Coastguard Worker 
178*635a8641SAndroid Build Coastguard Worker  private:
179*635a8641SAndroid Build Coastguard Worker   template <typename U>
180*635a8641SAndroid Build Coastguard Worker   friend scoped_refptr<U> base::AdoptRef(U*);
181*635a8641SAndroid Build Coastguard Worker 
Adopted()182*635a8641SAndroid Build Coastguard Worker   void Adopted() const {
183*635a8641SAndroid Build Coastguard Worker #if DCHECK_IS_ON()
184*635a8641SAndroid Build Coastguard Worker     DCHECK(needs_adopt_ref_);
185*635a8641SAndroid Build Coastguard Worker     needs_adopt_ref_ = false;
186*635a8641SAndroid Build Coastguard Worker #endif
187*635a8641SAndroid Build Coastguard Worker   }
188*635a8641SAndroid Build Coastguard Worker 
AddRefImpl()189*635a8641SAndroid Build Coastguard Worker   ALWAYS_INLINE void AddRefImpl() const {
190*635a8641SAndroid Build Coastguard Worker #if DCHECK_IS_ON()
191*635a8641SAndroid Build Coastguard Worker     DCHECK(!in_dtor_);
192*635a8641SAndroid Build Coastguard Worker     DCHECK(!needs_adopt_ref_)
193*635a8641SAndroid Build Coastguard Worker         << "This RefCounted object is created with non-zero reference count."
194*635a8641SAndroid Build Coastguard Worker         << " The first reference to such a object has to be made by AdoptRef or"
195*635a8641SAndroid Build Coastguard Worker         << " MakeRefCounted.";
196*635a8641SAndroid Build Coastguard Worker #endif
197*635a8641SAndroid Build Coastguard Worker     ref_count_.Increment();
198*635a8641SAndroid Build Coastguard Worker   }
199*635a8641SAndroid Build Coastguard Worker 
ReleaseImpl()200*635a8641SAndroid Build Coastguard Worker   ALWAYS_INLINE bool ReleaseImpl() const {
201*635a8641SAndroid Build Coastguard Worker #if DCHECK_IS_ON()
202*635a8641SAndroid Build Coastguard Worker     DCHECK(!in_dtor_);
203*635a8641SAndroid Build Coastguard Worker     DCHECK(!ref_count_.IsZero());
204*635a8641SAndroid Build Coastguard Worker #endif
205*635a8641SAndroid Build Coastguard Worker     if (!ref_count_.Decrement()) {
206*635a8641SAndroid Build Coastguard Worker #if DCHECK_IS_ON()
207*635a8641SAndroid Build Coastguard Worker       in_dtor_ = true;
208*635a8641SAndroid Build Coastguard Worker #endif
209*635a8641SAndroid Build Coastguard Worker       return true;
210*635a8641SAndroid Build Coastguard Worker     }
211*635a8641SAndroid Build Coastguard Worker     return false;
212*635a8641SAndroid Build Coastguard Worker   }
213*635a8641SAndroid Build Coastguard Worker 
214*635a8641SAndroid Build Coastguard Worker   mutable AtomicRefCount ref_count_{0};
215*635a8641SAndroid Build Coastguard Worker #if DCHECK_IS_ON()
216*635a8641SAndroid Build Coastguard Worker   mutable bool needs_adopt_ref_ = false;
217*635a8641SAndroid Build Coastguard Worker   mutable bool in_dtor_ = false;
218*635a8641SAndroid Build Coastguard Worker #endif
219*635a8641SAndroid Build Coastguard Worker 
220*635a8641SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafeBase);
221*635a8641SAndroid Build Coastguard Worker };
222*635a8641SAndroid Build Coastguard Worker 
223*635a8641SAndroid Build Coastguard Worker }  // namespace subtle
224*635a8641SAndroid Build Coastguard Worker 
225*635a8641SAndroid Build Coastguard Worker // ScopedAllowCrossThreadRefCountAccess disables the check documented on
226*635a8641SAndroid Build Coastguard Worker // RefCounted below for rare pre-existing use cases where thread-safety was
227*635a8641SAndroid Build Coastguard Worker // guaranteed through other means (e.g. explicit sequencing of calls across
228*635a8641SAndroid Build Coastguard Worker // execution sequences when bouncing between threads in order). New callers
229*635a8641SAndroid Build Coastguard Worker // should refrain from using this (callsites handling thread-safety through
230*635a8641SAndroid Build Coastguard Worker // locks should use RefCountedThreadSafe per the overhead of its atomics being
231*635a8641SAndroid Build Coastguard Worker // negligible compared to locks anyways and callsites doing explicit sequencing
232*635a8641SAndroid Build Coastguard Worker // should properly std::move() the ref to avoid hitting this check).
233*635a8641SAndroid Build Coastguard Worker // TODO(tzik): Cleanup existing use cases and remove
234*635a8641SAndroid Build Coastguard Worker // ScopedAllowCrossThreadRefCountAccess.
235*635a8641SAndroid Build Coastguard Worker class BASE_EXPORT ScopedAllowCrossThreadRefCountAccess final {
236*635a8641SAndroid Build Coastguard Worker  public:
237*635a8641SAndroid Build Coastguard Worker #if DCHECK_IS_ON()
238*635a8641SAndroid Build Coastguard Worker   ScopedAllowCrossThreadRefCountAccess();
239*635a8641SAndroid Build Coastguard Worker   ~ScopedAllowCrossThreadRefCountAccess();
240*635a8641SAndroid Build Coastguard Worker #else
241*635a8641SAndroid Build Coastguard Worker   ScopedAllowCrossThreadRefCountAccess() {}
242*635a8641SAndroid Build Coastguard Worker   ~ScopedAllowCrossThreadRefCountAccess() {}
243*635a8641SAndroid Build Coastguard Worker #endif
244*635a8641SAndroid Build Coastguard Worker };
245*635a8641SAndroid Build Coastguard Worker 
246*635a8641SAndroid Build Coastguard Worker //
247*635a8641SAndroid Build Coastguard Worker // A base class for reference counted classes.  Otherwise, known as a cheap
248*635a8641SAndroid Build Coastguard Worker // knock-off of WebKit's RefCounted<T> class.  To use this, just extend your
249*635a8641SAndroid Build Coastguard Worker // class from it like so:
250*635a8641SAndroid Build Coastguard Worker //
251*635a8641SAndroid Build Coastguard Worker //   class MyFoo : public base::RefCounted<MyFoo> {
252*635a8641SAndroid Build Coastguard Worker //    ...
253*635a8641SAndroid Build Coastguard Worker //    private:
254*635a8641SAndroid Build Coastguard Worker //     friend class base::RefCounted<MyFoo>;
255*635a8641SAndroid Build Coastguard Worker //     ~MyFoo();
256*635a8641SAndroid Build Coastguard Worker //   };
257*635a8641SAndroid Build Coastguard Worker //
258*635a8641SAndroid Build Coastguard Worker // You should always make your destructor non-public, to avoid any code deleting
259*635a8641SAndroid Build Coastguard Worker // the object accidently while there are references to it.
260*635a8641SAndroid Build Coastguard Worker //
261*635a8641SAndroid Build Coastguard Worker //
262*635a8641SAndroid Build Coastguard Worker // The ref count manipulation to RefCounted is NOT thread safe and has DCHECKs
263*635a8641SAndroid Build Coastguard Worker // to trap unsafe cross thread usage. A subclass instance of RefCounted can be
264*635a8641SAndroid Build Coastguard Worker // passed to another execution sequence only when its ref count is 1. If the ref
265*635a8641SAndroid Build Coastguard Worker // count is more than 1, the RefCounted class verifies the ref updates are made
266*635a8641SAndroid Build Coastguard Worker // on the same execution sequence as the previous ones. The subclass can also
267*635a8641SAndroid Build Coastguard Worker // manually call IsOnValidSequence to trap other non-thread-safe accesses; see
268*635a8641SAndroid Build Coastguard Worker // the documentation for that method.
269*635a8641SAndroid Build Coastguard Worker //
270*635a8641SAndroid Build Coastguard Worker //
271*635a8641SAndroid Build Coastguard Worker // The reference count starts from zero by default, and we intended to migrate
272*635a8641SAndroid Build Coastguard Worker // to start-from-one ref count. Put REQUIRE_ADOPTION_FOR_REFCOUNTED_TYPE() to
273*635a8641SAndroid Build Coastguard Worker // the ref counted class to opt-in.
274*635a8641SAndroid Build Coastguard Worker //
275*635a8641SAndroid Build Coastguard Worker // If an object has start-from-one ref count, the first scoped_refptr need to be
276*635a8641SAndroid Build Coastguard Worker // created by base::AdoptRef() or base::MakeRefCounted(). We can use
277*635a8641SAndroid Build Coastguard Worker // base::MakeRefCounted() to create create both type of ref counted object.
278*635a8641SAndroid Build Coastguard Worker //
279*635a8641SAndroid Build Coastguard Worker // The motivations to use start-from-one ref count are:
280*635a8641SAndroid Build Coastguard Worker //  - Start-from-one ref count doesn't need the ref count increment for the
281*635a8641SAndroid Build Coastguard Worker //    first reference.
282*635a8641SAndroid Build Coastguard Worker //  - It can detect an invalid object acquisition for a being-deleted object
283*635a8641SAndroid Build Coastguard Worker //    that has zero ref count. That tends to happen on custom deleter that
284*635a8641SAndroid Build Coastguard Worker //    delays the deletion.
285*635a8641SAndroid Build Coastguard Worker //    TODO(tzik): Implement invalid acquisition detection.
286*635a8641SAndroid Build Coastguard Worker //  - Behavior parity to Blink's WTF::RefCounted, whose count starts from one.
287*635a8641SAndroid Build Coastguard Worker //    And start-from-one ref count is a step to merge WTF::RefCounted into
288*635a8641SAndroid Build Coastguard Worker //    base::RefCounted.
289*635a8641SAndroid Build Coastguard Worker //
290*635a8641SAndroid Build Coastguard Worker #define REQUIRE_ADOPTION_FOR_REFCOUNTED_TYPE()             \
291*635a8641SAndroid Build Coastguard Worker   static constexpr ::base::subtle::StartRefCountFromOneTag \
292*635a8641SAndroid Build Coastguard Worker       kRefCountPreference = ::base::subtle::kStartRefCountFromOneTag
293*635a8641SAndroid Build Coastguard Worker 
294*635a8641SAndroid Build Coastguard Worker template <class T, typename Traits>
295*635a8641SAndroid Build Coastguard Worker class RefCounted;
296*635a8641SAndroid Build Coastguard Worker 
297*635a8641SAndroid Build Coastguard Worker template <typename T>
298*635a8641SAndroid Build Coastguard Worker struct DefaultRefCountedTraits {
DestructDefaultRefCountedTraits299*635a8641SAndroid Build Coastguard Worker   static void Destruct(const T* x) {
300*635a8641SAndroid Build Coastguard Worker     RefCounted<T, DefaultRefCountedTraits>::DeleteInternal(x);
301*635a8641SAndroid Build Coastguard Worker   }
302*635a8641SAndroid Build Coastguard Worker };
303*635a8641SAndroid Build Coastguard Worker 
304*635a8641SAndroid Build Coastguard Worker template <class T, typename Traits = DefaultRefCountedTraits<T>>
305*635a8641SAndroid Build Coastguard Worker class RefCounted : public subtle::RefCountedBase {
306*635a8641SAndroid Build Coastguard Worker  public:
307*635a8641SAndroid Build Coastguard Worker   static constexpr subtle::StartRefCountFromZeroTag kRefCountPreference =
308*635a8641SAndroid Build Coastguard Worker       subtle::kStartRefCountFromZeroTag;
309*635a8641SAndroid Build Coastguard Worker 
RefCounted()310*635a8641SAndroid Build Coastguard Worker   RefCounted() : subtle::RefCountedBase(T::kRefCountPreference) {}
311*635a8641SAndroid Build Coastguard Worker 
AddRef()312*635a8641SAndroid Build Coastguard Worker   void AddRef() const {
313*635a8641SAndroid Build Coastguard Worker     subtle::RefCountedBase::AddRef();
314*635a8641SAndroid Build Coastguard Worker   }
315*635a8641SAndroid Build Coastguard Worker 
Release()316*635a8641SAndroid Build Coastguard Worker   void Release() const {
317*635a8641SAndroid Build Coastguard Worker     if (subtle::RefCountedBase::Release()) {
318*635a8641SAndroid Build Coastguard Worker       // Prune the code paths which the static analyzer may take to simulate
319*635a8641SAndroid Build Coastguard Worker       // object destruction. Use-after-free errors aren't possible given the
320*635a8641SAndroid Build Coastguard Worker       // lifetime guarantees of the refcounting system.
321*635a8641SAndroid Build Coastguard Worker       ANALYZER_SKIP_THIS_PATH();
322*635a8641SAndroid Build Coastguard Worker 
323*635a8641SAndroid Build Coastguard Worker       Traits::Destruct(static_cast<const T*>(this));
324*635a8641SAndroid Build Coastguard Worker     }
325*635a8641SAndroid Build Coastguard Worker   }
326*635a8641SAndroid Build Coastguard Worker 
327*635a8641SAndroid Build Coastguard Worker  protected:
328*635a8641SAndroid Build Coastguard Worker   ~RefCounted() = default;
329*635a8641SAndroid Build Coastguard Worker 
330*635a8641SAndroid Build Coastguard Worker  private:
331*635a8641SAndroid Build Coastguard Worker   friend struct DefaultRefCountedTraits<T>;
332*635a8641SAndroid Build Coastguard Worker   template <typename U>
333*635a8641SAndroid Build Coastguard Worker   static void DeleteInternal(const U* x) {
334*635a8641SAndroid Build Coastguard Worker     delete x;
335*635a8641SAndroid Build Coastguard Worker   }
336*635a8641SAndroid Build Coastguard Worker 
337*635a8641SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(RefCounted);
338*635a8641SAndroid Build Coastguard Worker };
339*635a8641SAndroid Build Coastguard Worker 
340*635a8641SAndroid Build Coastguard Worker // Forward declaration.
341*635a8641SAndroid Build Coastguard Worker template <class T, typename Traits> class RefCountedThreadSafe;
342*635a8641SAndroid Build Coastguard Worker 
343*635a8641SAndroid Build Coastguard Worker // Default traits for RefCountedThreadSafe<T>.  Deletes the object when its ref
344*635a8641SAndroid Build Coastguard Worker // count reaches 0.  Overload to delete it on a different thread etc.
345*635a8641SAndroid Build Coastguard Worker template<typename T>
346*635a8641SAndroid Build Coastguard Worker struct DefaultRefCountedThreadSafeTraits {
347*635a8641SAndroid Build Coastguard Worker   static void Destruct(const T* x) {
348*635a8641SAndroid Build Coastguard Worker     // Delete through RefCountedThreadSafe to make child classes only need to be
349*635a8641SAndroid Build Coastguard Worker     // friend with RefCountedThreadSafe instead of this struct, which is an
350*635a8641SAndroid Build Coastguard Worker     // implementation detail.
351*635a8641SAndroid Build Coastguard Worker     RefCountedThreadSafe<T,
352*635a8641SAndroid Build Coastguard Worker                          DefaultRefCountedThreadSafeTraits>::DeleteInternal(x);
353*635a8641SAndroid Build Coastguard Worker   }
354*635a8641SAndroid Build Coastguard Worker };
355*635a8641SAndroid Build Coastguard Worker 
356*635a8641SAndroid Build Coastguard Worker //
357*635a8641SAndroid Build Coastguard Worker // A thread-safe variant of RefCounted<T>
358*635a8641SAndroid Build Coastguard Worker //
359*635a8641SAndroid Build Coastguard Worker //   class MyFoo : public base::RefCountedThreadSafe<MyFoo> {
360*635a8641SAndroid Build Coastguard Worker //    ...
361*635a8641SAndroid Build Coastguard Worker //   };
362*635a8641SAndroid Build Coastguard Worker //
363*635a8641SAndroid Build Coastguard Worker // If you're using the default trait, then you should add compile time
364*635a8641SAndroid Build Coastguard Worker // asserts that no one else is deleting your object.  i.e.
365*635a8641SAndroid Build Coastguard Worker //    private:
366*635a8641SAndroid Build Coastguard Worker //     friend class base::RefCountedThreadSafe<MyFoo>;
367*635a8641SAndroid Build Coastguard Worker //     ~MyFoo();
368*635a8641SAndroid Build Coastguard Worker //
369*635a8641SAndroid Build Coastguard Worker // We can use REQUIRE_ADOPTION_FOR_REFCOUNTED_TYPE() with RefCountedThreadSafe
370*635a8641SAndroid Build Coastguard Worker // too. See the comment above the RefCounted definition for details.
371*635a8641SAndroid Build Coastguard Worker template <class T, typename Traits = DefaultRefCountedThreadSafeTraits<T> >
372*635a8641SAndroid Build Coastguard Worker class RefCountedThreadSafe : public subtle::RefCountedThreadSafeBase {
373*635a8641SAndroid Build Coastguard Worker  public:
374*635a8641SAndroid Build Coastguard Worker   static constexpr subtle::StartRefCountFromZeroTag kRefCountPreference =
375*635a8641SAndroid Build Coastguard Worker       subtle::kStartRefCountFromZeroTag;
376*635a8641SAndroid Build Coastguard Worker 
377*635a8641SAndroid Build Coastguard Worker   explicit RefCountedThreadSafe()
378*635a8641SAndroid Build Coastguard Worker       : subtle::RefCountedThreadSafeBase(T::kRefCountPreference) {}
379*635a8641SAndroid Build Coastguard Worker 
380*635a8641SAndroid Build Coastguard Worker   void AddRef() const {
381*635a8641SAndroid Build Coastguard Worker     subtle::RefCountedThreadSafeBase::AddRef();
382*635a8641SAndroid Build Coastguard Worker   }
383*635a8641SAndroid Build Coastguard Worker 
384*635a8641SAndroid Build Coastguard Worker   void Release() const {
385*635a8641SAndroid Build Coastguard Worker     if (subtle::RefCountedThreadSafeBase::Release()) {
386*635a8641SAndroid Build Coastguard Worker       ANALYZER_SKIP_THIS_PATH();
387*635a8641SAndroid Build Coastguard Worker       Traits::Destruct(static_cast<const T*>(this));
388*635a8641SAndroid Build Coastguard Worker     }
389*635a8641SAndroid Build Coastguard Worker   }
390*635a8641SAndroid Build Coastguard Worker 
391*635a8641SAndroid Build Coastguard Worker  protected:
392*635a8641SAndroid Build Coastguard Worker   ~RefCountedThreadSafe() = default;
393*635a8641SAndroid Build Coastguard Worker 
394*635a8641SAndroid Build Coastguard Worker  private:
395*635a8641SAndroid Build Coastguard Worker   friend struct DefaultRefCountedThreadSafeTraits<T>;
396*635a8641SAndroid Build Coastguard Worker   template <typename U>
397*635a8641SAndroid Build Coastguard Worker   static void DeleteInternal(const U* x) {
398*635a8641SAndroid Build Coastguard Worker     delete x;
399*635a8641SAndroid Build Coastguard Worker   }
400*635a8641SAndroid Build Coastguard Worker 
401*635a8641SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafe);
402*635a8641SAndroid Build Coastguard Worker };
403*635a8641SAndroid Build Coastguard Worker 
404*635a8641SAndroid Build Coastguard Worker //
405*635a8641SAndroid Build Coastguard Worker // A thread-safe wrapper for some piece of data so we can place other
406*635a8641SAndroid Build Coastguard Worker // things in scoped_refptrs<>.
407*635a8641SAndroid Build Coastguard Worker //
408*635a8641SAndroid Build Coastguard Worker template<typename T>
409*635a8641SAndroid Build Coastguard Worker class RefCountedData
410*635a8641SAndroid Build Coastguard Worker     : public base::RefCountedThreadSafe< base::RefCountedData<T> > {
411*635a8641SAndroid Build Coastguard Worker  public:
412*635a8641SAndroid Build Coastguard Worker   RefCountedData() : data() {}
413*635a8641SAndroid Build Coastguard Worker   RefCountedData(const T& in_value) : data(in_value) {}
414*635a8641SAndroid Build Coastguard Worker   RefCountedData(T&& in_value) : data(std::move(in_value)) {}
415*635a8641SAndroid Build Coastguard Worker 
416*635a8641SAndroid Build Coastguard Worker   T data;
417*635a8641SAndroid Build Coastguard Worker 
418*635a8641SAndroid Build Coastguard Worker  private:
419*635a8641SAndroid Build Coastguard Worker   friend class base::RefCountedThreadSafe<base::RefCountedData<T> >;
420*635a8641SAndroid Build Coastguard Worker   ~RefCountedData() = default;
421*635a8641SAndroid Build Coastguard Worker };
422*635a8641SAndroid Build Coastguard Worker 
423*635a8641SAndroid Build Coastguard Worker }  // namespace base
424*635a8641SAndroid Build Coastguard Worker 
425*635a8641SAndroid Build Coastguard Worker #endif  // BASE_MEMORY_REF_COUNTED_H_
426