File: weak_ptr.cc

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (130 lines) | stat: -rw-r--r-- 3,424 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// Copyright 2011 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/memory/weak_ptr.h"

#if DCHECK_IS_ON()
#include <ostream>

#include "base/debug/stack_trace.h"
#endif

namespace base::internal {

WeakReference::Flag::Flag() {
  // Flags only become bound when checked for validity, or invalidated,
  // so that we can check that later validity/invalidation operations on
  // the same Flag take place on the same sequenced thread.
  DETACH_FROM_SEQUENCE(sequence_checker_);
}

void WeakReference::Flag::Invalidate() {
  // The flag being invalidated with a single ref implies that there are no
  // weak pointers in existence. Allow deletion on other thread in this case.
#if DCHECK_IS_ON()
  std::unique_ptr<debug::StackTrace> bound_at;
  DCHECK(sequence_checker_.CalledOnValidSequence(&bound_at) || HasOneRef())
      << "WeakPtrs must be invalidated on the same sequenced thread as where "
      << "they are bound.\n"
      << (bound_at ? "This was bound at:\n" + bound_at->ToString() : "")
      << "Check failed at:";
#endif
  invalidated_.Set();
}

bool WeakReference::Flag::IsValid() const {
  // WeakPtrs must be checked on the same sequenced thread.
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  return !invalidated_.IsSet();
}

bool WeakReference::Flag::MaybeValid() const {
  return !invalidated_.IsSet();
}

#if DCHECK_IS_ON()
void WeakReference::Flag::DetachFromSequence() {
  DETACH_FROM_SEQUENCE(sequence_checker_);
}

void WeakReference::Flag::BindToCurrentSequence() {
  DETACH_FROM_SEQUENCE(sequence_checker_);
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
}
#endif

WeakReference::Flag::~Flag() = default;

WeakReference::WeakReference() = default;
WeakReference::WeakReference(const scoped_refptr<Flag>& flag) : flag_(flag) {}
WeakReference::~WeakReference() = default;

WeakReference::WeakReference(const WeakReference& other) = default;
WeakReference& WeakReference::operator=(const WeakReference& other) = default;

WeakReference::WeakReference(WeakReference&& other) noexcept = default;
WeakReference& WeakReference::operator=(WeakReference&& other) noexcept =
    default;

void WeakReference::Reset() {
  flag_ = nullptr;
}

bool WeakReference::IsValid() const {
  return flag_ && flag_->IsValid();
}

bool WeakReference::MaybeValid() const {
  return flag_ && flag_->MaybeValid();
}

WeakReferenceOwner::WeakReferenceOwner()
    : flag_(MakeRefCounted<WeakReference::Flag>()) {}

WeakReferenceOwner::~WeakReferenceOwner() {
  if (flag_) {
    flag_->Invalidate();
  }
}

WeakReference WeakReferenceOwner::GetRef() const {
#if DCHECK_IS_ON()
  DCHECK(flag_);
  // If we hold the last reference to the Flag then detach the SequenceChecker.
  if (!HasRefs()) {
    flag_->DetachFromSequence();
  }
#endif

  return WeakReference(flag_);
}

void WeakReferenceOwner::Invalidate() {
  DCHECK(flag_);
  flag_->Invalidate();
  flag_ = MakeRefCounted<WeakReference::Flag>();
}

void WeakReferenceOwner::InvalidateAndDoom() {
  DCHECK(flag_);
  flag_->Invalidate();
  flag_.reset();
}

void WeakReferenceOwner::BindToCurrentSequence() {
#if DCHECK_IS_ON()
  DCHECK(flag_);
  flag_->BindToCurrentSequence();
#endif
}

WeakPtrFactoryBase::WeakPtrFactoryBase(uintptr_t ptr) : ptr_(ptr) {
  DCHECK(ptr_);
}

WeakPtrFactoryBase::~WeakPtrFactoryBase() {
  ptr_ = 0;
}

}  // namespace base::internal