xref: /aosp_15_r20/external/libchrome/base/memory/weak_ptr.cc (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2011 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 #include "base/memory/weak_ptr.h"
6*635a8641SAndroid Build Coastguard Worker 
7*635a8641SAndroid Build Coastguard Worker namespace base {
8*635a8641SAndroid Build Coastguard Worker namespace internal {
9*635a8641SAndroid Build Coastguard Worker 
Flag()10*635a8641SAndroid Build Coastguard Worker WeakReference::Flag::Flag() : is_valid_(true) {
11*635a8641SAndroid Build Coastguard Worker   // Flags only become bound when checked for validity, or invalidated,
12*635a8641SAndroid Build Coastguard Worker   // so that we can check that later validity/invalidation operations on
13*635a8641SAndroid Build Coastguard Worker   // the same Flag take place on the same sequenced thread.
14*635a8641SAndroid Build Coastguard Worker   sequence_checker_.DetachFromSequence();
15*635a8641SAndroid Build Coastguard Worker }
16*635a8641SAndroid Build Coastguard Worker 
Invalidate()17*635a8641SAndroid Build Coastguard Worker void WeakReference::Flag::Invalidate() {
18*635a8641SAndroid Build Coastguard Worker   // The flag being invalidated with a single ref implies that there are no
19*635a8641SAndroid Build Coastguard Worker   // weak pointers in existence. Allow deletion on other thread in this case.
20*635a8641SAndroid Build Coastguard Worker   DCHECK(sequence_checker_.CalledOnValidSequence() || HasOneRef())
21*635a8641SAndroid Build Coastguard Worker       << "WeakPtrs must be invalidated on the same sequenced thread.";
22*635a8641SAndroid Build Coastguard Worker   is_valid_ = false;
23*635a8641SAndroid Build Coastguard Worker }
24*635a8641SAndroid Build Coastguard Worker 
IsValid() const25*635a8641SAndroid Build Coastguard Worker bool WeakReference::Flag::IsValid() const {
26*635a8641SAndroid Build Coastguard Worker   DCHECK(sequence_checker_.CalledOnValidSequence())
27*635a8641SAndroid Build Coastguard Worker       << "WeakPtrs must be checked on the same sequenced thread.";
28*635a8641SAndroid Build Coastguard Worker   return is_valid_;
29*635a8641SAndroid Build Coastguard Worker }
30*635a8641SAndroid Build Coastguard Worker 
31*635a8641SAndroid Build Coastguard Worker WeakReference::Flag::~Flag() = default;
32*635a8641SAndroid Build Coastguard Worker 
33*635a8641SAndroid Build Coastguard Worker WeakReference::WeakReference() = default;
34*635a8641SAndroid Build Coastguard Worker 
WeakReference(const scoped_refptr<Flag> & flag)35*635a8641SAndroid Build Coastguard Worker WeakReference::WeakReference(const scoped_refptr<Flag>& flag) : flag_(flag) {}
36*635a8641SAndroid Build Coastguard Worker 
37*635a8641SAndroid Build Coastguard Worker WeakReference::~WeakReference() = default;
38*635a8641SAndroid Build Coastguard Worker 
39*635a8641SAndroid Build Coastguard Worker WeakReference::WeakReference(WeakReference&& other) = default;
40*635a8641SAndroid Build Coastguard Worker 
41*635a8641SAndroid Build Coastguard Worker WeakReference::WeakReference(const WeakReference& other) = default;
42*635a8641SAndroid Build Coastguard Worker 
is_valid() const43*635a8641SAndroid Build Coastguard Worker bool WeakReference::is_valid() const {
44*635a8641SAndroid Build Coastguard Worker   return flag_ && flag_->IsValid();
45*635a8641SAndroid Build Coastguard Worker }
46*635a8641SAndroid Build Coastguard Worker 
47*635a8641SAndroid Build Coastguard Worker WeakReferenceOwner::WeakReferenceOwner() = default;
48*635a8641SAndroid Build Coastguard Worker 
~WeakReferenceOwner()49*635a8641SAndroid Build Coastguard Worker WeakReferenceOwner::~WeakReferenceOwner() {
50*635a8641SAndroid Build Coastguard Worker   Invalidate();
51*635a8641SAndroid Build Coastguard Worker }
52*635a8641SAndroid Build Coastguard Worker 
GetRef() const53*635a8641SAndroid Build Coastguard Worker WeakReference WeakReferenceOwner::GetRef() const {
54*635a8641SAndroid Build Coastguard Worker   // If we hold the last reference to the Flag then create a new one.
55*635a8641SAndroid Build Coastguard Worker   if (!HasRefs())
56*635a8641SAndroid Build Coastguard Worker     flag_ = new WeakReference::Flag();
57*635a8641SAndroid Build Coastguard Worker 
58*635a8641SAndroid Build Coastguard Worker   return WeakReference(flag_);
59*635a8641SAndroid Build Coastguard Worker }
60*635a8641SAndroid Build Coastguard Worker 
Invalidate()61*635a8641SAndroid Build Coastguard Worker void WeakReferenceOwner::Invalidate() {
62*635a8641SAndroid Build Coastguard Worker   if (flag_) {
63*635a8641SAndroid Build Coastguard Worker     flag_->Invalidate();
64*635a8641SAndroid Build Coastguard Worker     flag_ = nullptr;
65*635a8641SAndroid Build Coastguard Worker   }
66*635a8641SAndroid Build Coastguard Worker }
67*635a8641SAndroid Build Coastguard Worker 
WeakPtrBase()68*635a8641SAndroid Build Coastguard Worker WeakPtrBase::WeakPtrBase() : ptr_(0) {}
69*635a8641SAndroid Build Coastguard Worker 
70*635a8641SAndroid Build Coastguard Worker WeakPtrBase::~WeakPtrBase() = default;
71*635a8641SAndroid Build Coastguard Worker 
WeakPtrBase(const WeakReference & ref,uintptr_t ptr)72*635a8641SAndroid Build Coastguard Worker WeakPtrBase::WeakPtrBase(const WeakReference& ref, uintptr_t ptr)
73*635a8641SAndroid Build Coastguard Worker     : ref_(ref), ptr_(ptr) {
74*635a8641SAndroid Build Coastguard Worker   DCHECK(ptr_);
75*635a8641SAndroid Build Coastguard Worker }
76*635a8641SAndroid Build Coastguard Worker 
WeakPtrFactoryBase(uintptr_t ptr)77*635a8641SAndroid Build Coastguard Worker WeakPtrFactoryBase::WeakPtrFactoryBase(uintptr_t ptr) : ptr_(ptr) {
78*635a8641SAndroid Build Coastguard Worker   DCHECK(ptr_);
79*635a8641SAndroid Build Coastguard Worker }
80*635a8641SAndroid Build Coastguard Worker 
~WeakPtrFactoryBase()81*635a8641SAndroid Build Coastguard Worker WeakPtrFactoryBase::~WeakPtrFactoryBase() {
82*635a8641SAndroid Build Coastguard Worker   ptr_ = 0;
83*635a8641SAndroid Build Coastguard Worker }
84*635a8641SAndroid Build Coastguard Worker 
85*635a8641SAndroid Build Coastguard Worker }  // namespace internal
86*635a8641SAndroid Build Coastguard Worker }  // namespace base
87