Chromium Code Reviews| Index: base/memory/weak_ptr.cc |
| diff --git a/base/memory/weak_ptr.cc b/base/memory/weak_ptr.cc |
| index c179b80097cc674e1ad2e484b99909166dda860a..393cfb8ee50b7534c156095feb4c9d56cb73e715 100644 |
| --- a/base/memory/weak_ptr.cc |
| +++ b/base/memory/weak_ptr.cc |
| @@ -4,50 +4,53 @@ |
| #include "base/memory/weak_ptr.h" |
| +#include "base/debug/leak_annotations.h" |
| + |
| namespace base { |
| namespace internal { |
| -WeakReference::Flag::Flag() : is_valid_(true) { |
| +static constexpr uintptr_t kTrueMask = ~static_cast<uintptr_t>(0); |
| + |
| +WeakReference::Flag::Flag() : is_valid_(kTrueMask) { |
| +#if DCHECK_IS_ON() |
| // 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. |
| sequence_checker_.DetachFromSequence(); |
| +#endif |
| } |
| -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. |
| - DCHECK(sequence_checker_.CalledOnValidSequence() || HasOneRef()) |
| - << "WeakPtrs must be invalidated on the same sequenced thread."; |
| - is_valid_ = false; |
| -} |
| +WeakReference::Flag::Flag(WeakReference::Flag::NullFlagTag) : is_valid_(false) { |
| + // There is no need for sequence_checker_.DetachFromSequence() because the |
| + // null flag doesn't participate in the sequence checks. |
|
Nico
2017/06/28 14:54:09
Maybe add ", see DCHECK in Invalidate()"
hans
2017/06/28 20:37:35
Done.
|
| -bool WeakReference::Flag::IsValid() const { |
| - DCHECK(sequence_checker_.CalledOnValidSequence()) |
| - << "WeakPtrs must be checked on the same sequenced thread."; |
| - return is_valid_; |
| + AddRef(); // Stayin' alive. |
|
Nico
2017/06/28 14:54:09
Remove comment, software is serious business. (Or
hans
2017/06/28 20:37:34
Done.
|
| } |
| -WeakReference::Flag::~Flag() { |
| +WeakReference::Flag* WeakReference::Flag::nullFlag() { |
| + ANNOTATE_SCOPED_MEMORY_LEAK; |
|
Nico
2017/06/28 14:54:09
I don't think this is needed, lsan doesn't report
hans
2017/06/28 20:37:34
Done.
|
| + static Flag* g_null_flag = new Flag(kNullFlagTag); |
|
Nico
2017/06/28 14:54:09
If you wanted you could use CR_DEFINE_STATIC_LOCAL
hans
2017/06/28 20:37:35
I don't think that would provide much value really
|
| + return g_null_flag; |
| } |
| -WeakReference::WeakReference() { |
| -} |
| +WeakReference::Flag::~Flag() {} |
| -WeakReference::WeakReference(const Flag* flag) : flag_(flag) { |
| -} |
| +WeakReference::WeakReference() : flag_(Flag::nullFlag()) {} |
| WeakReference::~WeakReference() { |
| } |
| -WeakReference::WeakReference(WeakReference&& other) = default; |
| +WeakReference::WeakReference(const Flag* flag) : flag_(flag) {} |
| -WeakReference::WeakReference(const WeakReference& other) = default; |
| +WeakReference::WeakReference(WeakReference&& other) |
| + : flag_(std::move(other.flag_)) { |
| + other.flag_ = Flag::nullFlag(); |
| +} |
| -bool WeakReference::is_valid() const { return flag_.get() && flag_->IsValid(); } |
| +WeakReference::WeakReference(const WeakReference& other) = default; |
| -WeakReferenceOwner::WeakReferenceOwner() { |
| -} |
| +WeakReferenceOwner::WeakReferenceOwner() |
| + : flag_(WeakReference::Flag::nullFlag()) {} |
| WeakReferenceOwner::~WeakReferenceOwner() { |
| Invalidate(); |
| @@ -62,20 +65,22 @@ WeakReference WeakReferenceOwner::GetRef() const { |
| } |
| void WeakReferenceOwner::Invalidate() { |
| - if (flag_.get()) { |
| - flag_->Invalidate(); |
| - flag_ = NULL; |
| - } |
| + flag_->Invalidate(); |
| + flag_ = WeakReference::Flag::nullFlag(); |
| } |
| -WeakPtrBase::WeakPtrBase() { |
| -} |
| +WeakPtrBase::WeakPtrBase() : ptr_(0) {} |
| -WeakPtrBase::~WeakPtrBase() { |
| -} |
| +WeakPtrBase::~WeakPtrBase() {} |
| WeakPtrBase::WeakPtrBase(const WeakReference& ref) : ref_(ref) { |
| } |
| +WeakPtrFactoryBase::WeakPtrFactoryBase(uintptr_t ptr) : ptr_(ptr) {} |
| + |
| +WeakPtrFactoryBase::~WeakPtrFactoryBase() { |
| + ptr_ = 0; |
| +} |
| + |
| } // namespace internal |
| } // namespace base |