OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 // Weak pointers are pointers to an object that do not affect its lifetime, | 5 // Weak pointers are pointers to an object that do not affect its lifetime, |
6 // and which may be invalidated (i.e. reset to nullptr) by the object, or its | 6 // and which may be invalidated (i.e. reset to nullptr) by the object, or its |
7 // owner, at any time, most commonly when the object is about to be deleted. | 7 // owner, at any time, most commonly when the object is about to be deleted. |
8 | 8 |
9 // Weak pointers are useful when an object needs to be accessed safely by one | 9 // Weak pointers are useful when an object needs to be accessed safely by one |
10 // or more objects other than its owner, and those callers can cope with the | 10 // or more objects other than its owner, and those callers can cope with the |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 // DO NOT USE THESE CLASSES DIRECTLY YOURSELF. | 89 // DO NOT USE THESE CLASSES DIRECTLY YOURSELF. |
90 | 90 |
91 class BASE_EXPORT WeakReference { | 91 class BASE_EXPORT WeakReference { |
92 public: | 92 public: |
93 // Although Flag is bound to a specific SequencedTaskRunner, it may be | 93 // Although Flag is bound to a specific SequencedTaskRunner, it may be |
94 // deleted from another via base::WeakPtr::~WeakPtr(). | 94 // deleted from another via base::WeakPtr::~WeakPtr(). |
95 class BASE_EXPORT Flag : public RefCountedThreadSafe<Flag> { | 95 class BASE_EXPORT Flag : public RefCountedThreadSafe<Flag> { |
96 public: | 96 public: |
97 Flag(); | 97 Flag(); |
98 | 98 |
99 // Get a pointer to the "Null Flag", a sentinel object used by WeakReference | 99 void Invalidate(); |
100 // objects that don't point to a valid Flag, either because they're default | 100 bool IsValid() const; |
101 // constructed or because they have been invalidated. This can be used like | |
102 // any other Flag object, but it is invalidated already from the start, and | |
103 // its refcount will never reach zero. | |
104 static Flag* NullFlag(); | |
105 | |
106 void Invalidate() { | |
107 #if DCHECK_IS_ON() | |
108 if (this == NullFlag()) { | |
109 // The Null Flag does not participate in the sequence checks below. | |
110 // Since its state never changes, it can be accessed from any thread. | |
111 DCHECK(!is_valid_); | |
112 return; | |
113 } | |
114 // The flag being invalidated with a single ref implies that there are no | |
115 // weak pointers in existence. Allow deletion on other thread in this | |
116 // case. | |
117 DCHECK(sequence_checker_.CalledOnValidSequence() || HasOneRef()) | |
118 << "WeakPtrs must be invalidated on the same sequenced thread."; | |
119 #endif | |
120 is_valid_ = 0; | |
121 } | |
122 | |
123 // Returns a pointer-sized bitmask of all 1s if valid or all 0s otherwise. | |
124 uintptr_t IsValid() const { | |
125 #if DCHECK_IS_ON() | |
126 if (this == NullFlag()) { | |
127 // The Null Flag does not participate in the sequence checks below. | |
128 // Since its state never changes, it can be accessed from any thread. | |
129 DCHECK(!is_valid_); | |
130 return 0; | |
131 } | |
132 DCHECK(sequence_checker_.CalledOnValidSequence()) | |
133 << "WeakPtrs must be checked on the same sequenced thread."; | |
134 #endif | |
135 return is_valid_; | |
136 } | |
137 | 101 |
138 private: | 102 private: |
139 friend class base::RefCountedThreadSafe<Flag>; | 103 friend class base::RefCountedThreadSafe<Flag>; |
140 | 104 |
141 enum NullFlagTag { kNullFlagTag }; | |
142 Flag(NullFlagTag); | |
143 | |
144 ~Flag(); | 105 ~Flag(); |
145 | 106 |
146 uintptr_t is_valid_; | |
147 #if DCHECK_IS_ON() | |
148 // Even if SequenceChecker is an empty class in non-dcheck builds, it still | |
149 // takes up space in the class. | |
150 SequenceChecker sequence_checker_; | 107 SequenceChecker sequence_checker_; |
151 #endif | 108 bool is_valid_; |
152 }; | 109 }; |
153 | 110 |
154 WeakReference(); | 111 WeakReference(); |
155 explicit WeakReference(const Flag* flag); | 112 explicit WeakReference(const Flag* flag); |
156 ~WeakReference(); | 113 ~WeakReference(); |
157 | 114 |
158 WeakReference(WeakReference&& other); | 115 WeakReference(WeakReference&& other); |
159 WeakReference(const WeakReference& other); | 116 WeakReference(const WeakReference& other); |
160 WeakReference& operator=(WeakReference&& other) = default; | 117 WeakReference& operator=(WeakReference&& other) = default; |
161 WeakReference& operator=(const WeakReference& other) = default; | 118 WeakReference& operator=(const WeakReference& other) = default; |
162 | 119 |
163 uintptr_t is_valid() const { return flag_->IsValid(); } | 120 bool is_valid() const; |
164 | 121 |
165 private: | 122 private: |
166 // Note: To avoid null-checks, flag_ always points to either Flag::NullFlag() | |
167 // or some other object. | |
168 scoped_refptr<const Flag> flag_; | 123 scoped_refptr<const Flag> flag_; |
169 }; | 124 }; |
170 | 125 |
171 class BASE_EXPORT WeakReferenceOwner { | 126 class BASE_EXPORT WeakReferenceOwner { |
172 public: | 127 public: |
173 WeakReferenceOwner(); | 128 WeakReferenceOwner(); |
174 ~WeakReferenceOwner(); | 129 ~WeakReferenceOwner(); |
175 | 130 |
176 WeakReference GetRef() const; | 131 WeakReference GetRef() const; |
177 | 132 |
178 bool HasRefs() const { | 133 bool HasRefs() const { |
179 return flag_ != WeakReference::Flag::NullFlag() && !flag_->HasOneRef(); | 134 return flag_.get() && !flag_->HasOneRef(); |
180 } | 135 } |
181 | 136 |
182 void Invalidate(); | 137 void Invalidate(); |
183 | 138 |
184 private: | 139 private: |
185 mutable scoped_refptr<WeakReference::Flag> flag_; | 140 mutable scoped_refptr<WeakReference::Flag> flag_; |
186 }; | 141 }; |
187 | 142 |
188 // This class simplifies the implementation of WeakPtr's type conversion | 143 // This class simplifies the implementation of WeakPtr's type conversion |
189 // constructor by avoiding the need for a public accessor for ref_. A | 144 // constructor by avoiding the need for a public accessor for ref_. A |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
274 } | 229 } |
275 template <typename U> | 230 template <typename U> |
276 WeakPtr(WeakPtr<U>&& other) : WeakPtrBase(std::move(other)) { | 231 WeakPtr(WeakPtr<U>&& other) : WeakPtrBase(std::move(other)) { |
277 // Need to cast from U* to T* to do pointer adjustment in case of multiple | 232 // Need to cast from U* to T* to do pointer adjustment in case of multiple |
278 // inheritance. This also enforces the "U is a T" rule. | 233 // inheritance. This also enforces the "U is a T" rule. |
279 T* t = reinterpret_cast<U*>(other.ptr_); | 234 T* t = reinterpret_cast<U*>(other.ptr_); |
280 ptr_ = reinterpret_cast<uintptr_t>(t); | 235 ptr_ = reinterpret_cast<uintptr_t>(t); |
281 } | 236 } |
282 | 237 |
283 T* get() const { | 238 T* get() const { |
284 // Intentionally bitwise and; see command on Flag::IsValid(). This provides | 239 return ref_.is_valid() ? reinterpret_cast<T*>(ptr_) : nullptr; |
285 // a fast way of conditionally retrieving the pointer, and conveniently sets | |
286 // EFLAGS for any null-check performed by the caller. | |
287 return reinterpret_cast<T*>(ref_.is_valid() & ptr_); | |
288 } | 240 } |
289 | 241 |
290 T& operator*() const { | 242 T& operator*() const { |
291 DCHECK(get() != nullptr); | 243 DCHECK(get() != nullptr); |
292 return *get(); | 244 return *get(); |
293 } | 245 } |
294 T* operator->() const { | 246 T* operator->() const { |
295 DCHECK(get() != nullptr); | 247 DCHECK(get() != nullptr); |
296 return get(); | 248 return get(); |
297 } | 249 } |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
418 // base::WeakPtr<Derived> ptr = derived.AsWeakPtr(); // Fails. | 370 // base::WeakPtr<Derived> ptr = derived.AsWeakPtr(); // Fails. |
419 | 371 |
420 template <typename Derived> | 372 template <typename Derived> |
421 WeakPtr<Derived> AsWeakPtr(Derived* t) { | 373 WeakPtr<Derived> AsWeakPtr(Derived* t) { |
422 return internal::SupportsWeakPtrBase::StaticAsWeakPtr<Derived>(t); | 374 return internal::SupportsWeakPtrBase::StaticAsWeakPtr<Derived>(t); |
423 } | 375 } |
424 | 376 |
425 } // namespace base | 377 } // namespace base |
426 | 378 |
427 #endif // BASE_MEMORY_WEAK_PTR_H_ | 379 #endif // BASE_MEMORY_WEAK_PTR_H_ |
OLD | NEW |