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