1*6777b538SAndroid Build Coastguard Worker // Copyright 2011 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 #include "base/memory/weak_ptr.h" 6*6777b538SAndroid Build Coastguard Worker 7*6777b538SAndroid Build Coastguard Worker #if DCHECK_IS_ON() 8*6777b538SAndroid Build Coastguard Worker #include <ostream> 9*6777b538SAndroid Build Coastguard Worker 10*6777b538SAndroid Build Coastguard Worker #include "base/debug/stack_trace.h" 11*6777b538SAndroid Build Coastguard Worker #endif 12*6777b538SAndroid Build Coastguard Worker 13*6777b538SAndroid Build Coastguard Worker namespace base::internal { 14*6777b538SAndroid Build Coastguard Worker Flag()15*6777b538SAndroid Build Coastguard WorkerWeakReference::Flag::Flag() { 16*6777b538SAndroid Build Coastguard Worker // Flags only become bound when checked for validity, or invalidated, 17*6777b538SAndroid Build Coastguard Worker // so that we can check that later validity/invalidation operations on 18*6777b538SAndroid Build Coastguard Worker // the same Flag take place on the same sequenced thread. 19*6777b538SAndroid Build Coastguard Worker DETACH_FROM_SEQUENCE(sequence_checker_); 20*6777b538SAndroid Build Coastguard Worker } 21*6777b538SAndroid Build Coastguard Worker Invalidate()22*6777b538SAndroid Build Coastguard Workervoid WeakReference::Flag::Invalidate() { 23*6777b538SAndroid Build Coastguard Worker // The flag being invalidated with a single ref implies that there are no 24*6777b538SAndroid Build Coastguard Worker // weak pointers in existence. Allow deletion on other thread in this case. 25*6777b538SAndroid Build Coastguard Worker #if DCHECK_IS_ON() 26*6777b538SAndroid Build Coastguard Worker std::unique_ptr<debug::StackTrace> bound_at; 27*6777b538SAndroid Build Coastguard Worker DCHECK(sequence_checker_.CalledOnValidSequence(&bound_at) || HasOneRef()) 28*6777b538SAndroid Build Coastguard Worker << "WeakPtrs must be invalidated on the same sequenced thread as where " 29*6777b538SAndroid Build Coastguard Worker << "they are bound.\n" 30*6777b538SAndroid Build Coastguard Worker << (bound_at ? "This was bound at:\n" + bound_at->ToString() : "") 31*6777b538SAndroid Build Coastguard Worker << "Check failed at:"; 32*6777b538SAndroid Build Coastguard Worker #endif 33*6777b538SAndroid Build Coastguard Worker invalidated_.Set(); 34*6777b538SAndroid Build Coastguard Worker } 35*6777b538SAndroid Build Coastguard Worker IsValid() const36*6777b538SAndroid Build Coastguard Workerbool WeakReference::Flag::IsValid() const { 37*6777b538SAndroid Build Coastguard Worker // WeakPtrs must be checked on the same sequenced thread. 38*6777b538SAndroid Build Coastguard Worker DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 39*6777b538SAndroid Build Coastguard Worker return !invalidated_.IsSet(); 40*6777b538SAndroid Build Coastguard Worker } 41*6777b538SAndroid Build Coastguard Worker MaybeValid() const42*6777b538SAndroid Build Coastguard Workerbool WeakReference::Flag::MaybeValid() const { 43*6777b538SAndroid Build Coastguard Worker return !invalidated_.IsSet(); 44*6777b538SAndroid Build Coastguard Worker } 45*6777b538SAndroid Build Coastguard Worker 46*6777b538SAndroid Build Coastguard Worker #if DCHECK_IS_ON() DetachFromSequence()47*6777b538SAndroid Build Coastguard Workervoid WeakReference::Flag::DetachFromSequence() { 48*6777b538SAndroid Build Coastguard Worker DETACH_FROM_SEQUENCE(sequence_checker_); 49*6777b538SAndroid Build Coastguard Worker } 50*6777b538SAndroid Build Coastguard Worker BindToCurrentSequence()51*6777b538SAndroid Build Coastguard Workervoid WeakReference::Flag::BindToCurrentSequence() { 52*6777b538SAndroid Build Coastguard Worker DETACH_FROM_SEQUENCE(sequence_checker_); 53*6777b538SAndroid Build Coastguard Worker DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); 54*6777b538SAndroid Build Coastguard Worker } 55*6777b538SAndroid Build Coastguard Worker #endif 56*6777b538SAndroid Build Coastguard Worker 57*6777b538SAndroid Build Coastguard Worker WeakReference::Flag::~Flag() = default; 58*6777b538SAndroid Build Coastguard Worker 59*6777b538SAndroid Build Coastguard Worker WeakReference::WeakReference() = default; WeakReference(const scoped_refptr<Flag> & flag)60*6777b538SAndroid Build Coastguard WorkerWeakReference::WeakReference(const scoped_refptr<Flag>& flag) : flag_(flag) {} 61*6777b538SAndroid Build Coastguard Worker WeakReference::~WeakReference() = default; 62*6777b538SAndroid Build Coastguard Worker 63*6777b538SAndroid Build Coastguard Worker WeakReference::WeakReference(const WeakReference& other) = default; 64*6777b538SAndroid Build Coastguard Worker WeakReference& WeakReference::operator=(const WeakReference& other) = default; 65*6777b538SAndroid Build Coastguard Worker 66*6777b538SAndroid Build Coastguard Worker WeakReference::WeakReference(WeakReference&& other) noexcept = default; 67*6777b538SAndroid Build Coastguard Worker WeakReference& WeakReference::operator=(WeakReference&& other) noexcept = 68*6777b538SAndroid Build Coastguard Worker default; 69*6777b538SAndroid Build Coastguard Worker Reset()70*6777b538SAndroid Build Coastguard Workervoid WeakReference::Reset() { 71*6777b538SAndroid Build Coastguard Worker flag_ = nullptr; 72*6777b538SAndroid Build Coastguard Worker } 73*6777b538SAndroid Build Coastguard Worker IsValid() const74*6777b538SAndroid Build Coastguard Workerbool WeakReference::IsValid() const { 75*6777b538SAndroid Build Coastguard Worker return flag_ && flag_->IsValid(); 76*6777b538SAndroid Build Coastguard Worker } 77*6777b538SAndroid Build Coastguard Worker MaybeValid() const78*6777b538SAndroid Build Coastguard Workerbool WeakReference::MaybeValid() const { 79*6777b538SAndroid Build Coastguard Worker return flag_ && flag_->MaybeValid(); 80*6777b538SAndroid Build Coastguard Worker } 81*6777b538SAndroid Build Coastguard Worker WeakReferenceOwner()82*6777b538SAndroid Build Coastguard WorkerWeakReferenceOwner::WeakReferenceOwner() 83*6777b538SAndroid Build Coastguard Worker : flag_(MakeRefCounted<WeakReference::Flag>()) {} 84*6777b538SAndroid Build Coastguard Worker ~WeakReferenceOwner()85*6777b538SAndroid Build Coastguard WorkerWeakReferenceOwner::~WeakReferenceOwner() { 86*6777b538SAndroid Build Coastguard Worker flag_->Invalidate(); 87*6777b538SAndroid Build Coastguard Worker } 88*6777b538SAndroid Build Coastguard Worker GetRef() const89*6777b538SAndroid Build Coastguard WorkerWeakReference WeakReferenceOwner::GetRef() const { 90*6777b538SAndroid Build Coastguard Worker #if DCHECK_IS_ON() 91*6777b538SAndroid Build Coastguard Worker // If we hold the last reference to the Flag then detach the SequenceChecker. 92*6777b538SAndroid Build Coastguard Worker if (!HasRefs()) 93*6777b538SAndroid Build Coastguard Worker flag_->DetachFromSequence(); 94*6777b538SAndroid Build Coastguard Worker #endif 95*6777b538SAndroid Build Coastguard Worker 96*6777b538SAndroid Build Coastguard Worker return WeakReference(flag_); 97*6777b538SAndroid Build Coastguard Worker } 98*6777b538SAndroid Build Coastguard Worker Invalidate()99*6777b538SAndroid Build Coastguard Workervoid WeakReferenceOwner::Invalidate() { 100*6777b538SAndroid Build Coastguard Worker flag_->Invalidate(); 101*6777b538SAndroid Build Coastguard Worker flag_ = MakeRefCounted<WeakReference::Flag>(); 102*6777b538SAndroid Build Coastguard Worker } 103*6777b538SAndroid Build Coastguard Worker BindToCurrentSequence()104*6777b538SAndroid Build Coastguard Workervoid WeakReferenceOwner::BindToCurrentSequence() { 105*6777b538SAndroid Build Coastguard Worker #if DCHECK_IS_ON() 106*6777b538SAndroid Build Coastguard Worker flag_->BindToCurrentSequence(); 107*6777b538SAndroid Build Coastguard Worker #endif 108*6777b538SAndroid Build Coastguard Worker } 109*6777b538SAndroid Build Coastguard Worker WeakPtrFactoryBase(uintptr_t ptr)110*6777b538SAndroid Build Coastguard WorkerWeakPtrFactoryBase::WeakPtrFactoryBase(uintptr_t ptr) : ptr_(ptr) { 111*6777b538SAndroid Build Coastguard Worker DCHECK(ptr_); 112*6777b538SAndroid Build Coastguard Worker } 113*6777b538SAndroid Build Coastguard Worker ~WeakPtrFactoryBase()114*6777b538SAndroid Build Coastguard WorkerWeakPtrFactoryBase::~WeakPtrFactoryBase() { 115*6777b538SAndroid Build Coastguard Worker ptr_ = 0; 116*6777b538SAndroid Build Coastguard Worker } 117*6777b538SAndroid Build Coastguard Worker 118*6777b538SAndroid Build Coastguard Worker } // namespace base::internal 119