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