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