| OLD | NEW | 
|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "base/memory/weak_ptr.h" | 5 #include "base/memory/weak_ptr.h" | 
| 6 | 6 | 
| 7 namespace base { | 7 namespace base { | 
| 8 namespace internal { | 8 namespace internal { | 
| 9 | 9 | 
| 10 WeakReference::Flag::Flag() : is_valid_(true) { | 10 static constexpr uintptr_t kTrueMask = ~static_cast<uintptr_t>(0); | 
|  | 11 | 
|  | 12 WeakReference::Flag::Flag() : is_valid_(kTrueMask) { | 
|  | 13 #if DCHECK_IS_ON() | 
| 11   // Flags only become bound when checked for validity, or invalidated, | 14   // Flags only become bound when checked for validity, or invalidated, | 
| 12   // so that we can check that later validity/invalidation operations on | 15   // so that we can check that later validity/invalidation operations on | 
| 13   // the same Flag take place on the same sequenced thread. | 16   // the same Flag take place on the same sequenced thread. | 
| 14   sequence_checker_.DetachFromSequence(); | 17   sequence_checker_.DetachFromSequence(); | 
|  | 18 #endif | 
| 15 } | 19 } | 
| 16 | 20 | 
| 17 void WeakReference::Flag::Invalidate() { | 21 WeakReference::Flag::Flag(WeakReference::Flag::NullFlagTag) : is_valid_(false) { | 
| 18   // The flag being invalidated with a single ref implies that there are no | 22   // There is no need for sequence_checker_.DetachFromSequence() because the | 
| 19   // weak pointers in existence. Allow deletion on other thread in this case. | 23   // null flag doesn't participate in the sequence checks. See DCHECK in | 
| 20   DCHECK(sequence_checker_.CalledOnValidSequence() || HasOneRef()) | 24   // Invalidate() and IsValid(). | 
| 21       << "WeakPtrs must be invalidated on the same sequenced thread."; | 25 | 
| 22   is_valid_ = false; | 26   // Keep the object alive perpetually, even when there are no references to it. | 
|  | 27   AddRef(); | 
| 23 } | 28 } | 
| 24 | 29 | 
| 25 bool WeakReference::Flag::IsValid() const { | 30 WeakReference::Flag* WeakReference::Flag::NullFlag() { | 
| 26   DCHECK(sequence_checker_.CalledOnValidSequence()) | 31   static Flag* g_null_flag = new Flag(kNullFlagTag); | 
| 27       << "WeakPtrs must be checked on the same sequenced thread."; | 32   return g_null_flag; | 
| 28   return is_valid_; |  | 
| 29 } | 33 } | 
| 30 | 34 | 
| 31 WeakReference::Flag::~Flag() { | 35 WeakReference::Flag::~Flag() {} | 
| 32 } |  | 
| 33 | 36 | 
| 34 WeakReference::WeakReference() { | 37 WeakReference::WeakReference() : flag_(Flag::NullFlag()) {} | 
| 35 } |  | 
| 36 |  | 
| 37 WeakReference::WeakReference(const Flag* flag) : flag_(flag) { |  | 
| 38 } |  | 
| 39 | 38 | 
| 40 WeakReference::~WeakReference() { | 39 WeakReference::~WeakReference() { | 
| 41 } | 40 } | 
| 42 | 41 | 
| 43 WeakReference::WeakReference(WeakReference&& other) = default; | 42 WeakReference::WeakReference(const Flag* flag) : flag_(flag) {} | 
|  | 43 | 
|  | 44 WeakReference::WeakReference(WeakReference&& other) | 
|  | 45     : flag_(std::move(other.flag_)) { | 
|  | 46   other.flag_ = Flag::NullFlag(); | 
|  | 47 } | 
| 44 | 48 | 
| 45 WeakReference::WeakReference(const WeakReference& other) = default; | 49 WeakReference::WeakReference(const WeakReference& other) = default; | 
| 46 | 50 | 
| 47 bool WeakReference::is_valid() const { return flag_.get() && flag_->IsValid(); } | 51 WeakReferenceOwner::WeakReferenceOwner() | 
| 48 | 52     : flag_(WeakReference::Flag::NullFlag()) {} | 
| 49 WeakReferenceOwner::WeakReferenceOwner() { |  | 
| 50 } |  | 
| 51 | 53 | 
| 52 WeakReferenceOwner::~WeakReferenceOwner() { | 54 WeakReferenceOwner::~WeakReferenceOwner() { | 
| 53   Invalidate(); | 55   Invalidate(); | 
| 54 } | 56 } | 
| 55 | 57 | 
| 56 WeakReference WeakReferenceOwner::GetRef() const { | 58 WeakReference WeakReferenceOwner::GetRef() const { | 
| 57   // If we hold the last reference to the Flag then create a new one. | 59   // If we hold the last reference to the Flag then create a new one. | 
| 58   if (!HasRefs()) | 60   if (!HasRefs()) | 
| 59     flag_ = new WeakReference::Flag(); | 61     flag_ = new WeakReference::Flag(); | 
| 60 | 62 | 
| 61   return WeakReference(flag_.get()); | 63   return WeakReference(flag_.get()); | 
| 62 } | 64 } | 
| 63 | 65 | 
| 64 void WeakReferenceOwner::Invalidate() { | 66 void WeakReferenceOwner::Invalidate() { | 
| 65   if (flag_.get()) { | 67   flag_->Invalidate(); | 
| 66     flag_->Invalidate(); | 68   flag_ = WeakReference::Flag::NullFlag(); | 
| 67     flag_ = NULL; |  | 
| 68   } |  | 
| 69 } | 69 } | 
| 70 | 70 | 
| 71 WeakPtrBase::WeakPtrBase() { | 71 WeakPtrBase::WeakPtrBase() { | 
| 72 } | 72 } | 
| 73 | 73 | 
| 74 WeakPtrBase::~WeakPtrBase() { | 74 WeakPtrBase::~WeakPtrBase() { | 
| 75 } | 75 } | 
| 76 | 76 | 
| 77 WeakPtrBase::WeakPtrBase(const WeakReference& ref) : ref_(ref) { | 77 WeakPtrBase::WeakPtrBase(const WeakReference& ref) : ref_(ref) { | 
| 78 } | 78 } | 
| 79 | 79 | 
| 80 }  // namespace internal | 80 }  // namespace internal | 
| 81 }  // namespace base | 81 }  // namespace base | 
| OLD | NEW | 
|---|