weak_ptr.cc 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. // Copyright (c) 2011 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "base/memory/weak_ptr.h"
  5. #if DCHECK_IS_ON()
  6. #include <ostream>
  7. #include "base/debug/stack_trace.h"
  8. #endif
  9. namespace base {
  10. namespace internal {
  11. WeakReference::Flag::Flag() {
  12. // Flags only become bound when checked for validity, or invalidated,
  13. // so that we can check that later validity/invalidation operations on
  14. // the same Flag take place on the same sequenced thread.
  15. DETACH_FROM_SEQUENCE(sequence_checker_);
  16. }
  17. void WeakReference::Flag::Invalidate() {
  18. // The flag being invalidated with a single ref implies that there are no
  19. // weak pointers in existence. Allow deletion on other thread in this case.
  20. #if DCHECK_IS_ON()
  21. std::unique_ptr<debug::StackTrace> bound_at;
  22. DCHECK(sequence_checker_.CalledOnValidSequence(&bound_at) || HasOneRef())
  23. << "WeakPtrs must be invalidated on the same sequenced thread as where "
  24. << "they are bound.\n"
  25. << (bound_at ? "This was bound at:\n" + bound_at->ToString() : "")
  26. << "Check failed at:";
  27. #endif
  28. invalidated_.Set();
  29. }
  30. bool WeakReference::Flag::IsValid() const {
  31. // WeakPtrs must be checked on the same sequenced thread.
  32. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  33. return !invalidated_.IsSet();
  34. }
  35. bool WeakReference::Flag::MaybeValid() const {
  36. return !invalidated_.IsSet();
  37. }
  38. #if DCHECK_IS_ON()
  39. void WeakReference::Flag::DetachFromSequence() {
  40. DETACH_FROM_SEQUENCE(sequence_checker_);
  41. }
  42. #endif
  43. WeakReference::Flag::~Flag() = default;
  44. WeakReference::WeakReference() = default;
  45. WeakReference::WeakReference(const scoped_refptr<Flag>& flag) : flag_(flag) {}
  46. WeakReference::~WeakReference() = default;
  47. WeakReference::WeakReference(WeakReference&& other) noexcept = default;
  48. WeakReference::WeakReference(const WeakReference& other) = default;
  49. bool WeakReference::IsValid() const {
  50. return flag_ && flag_->IsValid();
  51. }
  52. bool WeakReference::MaybeValid() const {
  53. return flag_ && flag_->MaybeValid();
  54. }
  55. WeakReferenceOwner::WeakReferenceOwner()
  56. : flag_(MakeRefCounted<WeakReference::Flag>()) {}
  57. WeakReferenceOwner::~WeakReferenceOwner() {
  58. flag_->Invalidate();
  59. }
  60. WeakReference WeakReferenceOwner::GetRef() const {
  61. #if DCHECK_IS_ON()
  62. // If we hold the last reference to the Flag then detach the SequenceChecker.
  63. if (!HasRefs())
  64. flag_->DetachFromSequence();
  65. #endif
  66. return WeakReference(flag_);
  67. }
  68. void WeakReferenceOwner::Invalidate() {
  69. flag_->Invalidate();
  70. flag_ = MakeRefCounted<WeakReference::Flag>();
  71. }
  72. WeakPtrBase::WeakPtrBase() : ptr_(0) {}
  73. WeakPtrBase::~WeakPtrBase() = default;
  74. WeakPtrBase::WeakPtrBase(const WeakReference& ref, uintptr_t ptr)
  75. : ref_(ref), ptr_(ptr) {
  76. DCHECK(ptr_);
  77. }
  78. WeakPtrFactoryBase::WeakPtrFactoryBase(uintptr_t ptr) : ptr_(ptr) {
  79. DCHECK(ptr_);
  80. }
  81. WeakPtrFactoryBase::~WeakPtrFactoryBase() {
  82. ptr_ = 0;
  83. }
  84. } // namespace internal
  85. } // namespace base