xref: /aosp_15_r20/external/cronet/base/memory/weak_ptr.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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 Worker WeakReference::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 Worker void 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 Worker bool 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 Worker bool 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 Worker void 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 Worker void 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 Worker WeakReference::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 Worker void WeakReference::Reset() {
71*6777b538SAndroid Build Coastguard Worker   flag_ = nullptr;
72*6777b538SAndroid Build Coastguard Worker }
73*6777b538SAndroid Build Coastguard Worker 
IsValid() const74*6777b538SAndroid Build Coastguard Worker bool 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 Worker bool 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 Worker WeakReferenceOwner::WeakReferenceOwner()
83*6777b538SAndroid Build Coastguard Worker     : flag_(MakeRefCounted<WeakReference::Flag>()) {}
84*6777b538SAndroid Build Coastguard Worker 
~WeakReferenceOwner()85*6777b538SAndroid Build Coastguard Worker WeakReferenceOwner::~WeakReferenceOwner() {
86*6777b538SAndroid Build Coastguard Worker   flag_->Invalidate();
87*6777b538SAndroid Build Coastguard Worker }
88*6777b538SAndroid Build Coastguard Worker 
GetRef() const89*6777b538SAndroid Build Coastguard Worker WeakReference 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 Worker void 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 Worker void 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 Worker WeakPtrFactoryBase::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 Worker WeakPtrFactoryBase::~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