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 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
88 // These classes are part of the WeakPtr implementation. | 88 // These classes are part of the WeakPtr implementation. |
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 static Flag* nullFlag(); | |
Nico
2017/06/28 14:54:10
google (and chromium) style spells functions NullF
hans
2017/06/28 20:37:35
Done.
| |
98 | 99 |
99 void Invalidate(); | 100 void Invalidate() { |
100 bool IsValid() const; | 101 #if DCHECK_IS_ON() |
102 if (this == nullFlag()) | |
103 return; | |
Nico
2017/06/28 14:54:09
This looks kind of confusing – do you not want to
hans
2017/06/28 20:37:35
I've tried to make this clearer with a comment. Th
| |
104 // The flag being invalidated with a single ref implies that there are no | |
105 // weak pointers in existence. Allow deletion on other thread in this | |
106 // case. | |
107 DCHECK(sequence_checker_.CalledOnValidSequence() || HasOneRef()) | |
108 << "WeakPtrs must be invalidated on the same sequenced thread."; | |
109 #endif | |
110 is_valid_ = 0; | |
111 } | |
112 uintptr_t IsValid() const { | |
Nico
2017/06/28 14:54:10
Add comment that this returns either all 0s or all
hans
2017/06/28 20:37:35
Done.
| |
113 #if DCHECK_IS_ON() | |
114 if (this == nullFlag()) { | |
115 DCHECK(!is_valid_); | |
116 return 0; | |
117 } | |
118 DCHECK(sequence_checker_.CalledOnValidSequence()) | |
119 << "WeakPtrs must be checked on the same sequenced thread."; | |
120 #endif | |
121 return is_valid_; | |
122 } | |
101 | 123 |
102 private: | 124 private: |
103 friend class base::RefCountedThreadSafe<Flag>; | 125 friend class base::RefCountedThreadSafe<Flag>; |
104 | 126 |
127 enum NullFlagTag { kNullFlagTag }; | |
128 Flag(NullFlagTag); | |
129 | |
105 ~Flag(); | 130 ~Flag(); |
106 | 131 |
132 uintptr_t is_valid_; | |
133 #if DCHECK_IS_ON() | |
134 // Even if SequenceChecker is an empty class in non-dcheck builds, it still | |
135 // takes up space in the class. | |
Nico
2017/06/28 14:36:56
This bit seems unrelated to what's in the CL descr
hans
2017/06/28 20:37:35
It's related in that it keeps the size from growin
Nico
2017/06/28 20:57:03
Ah ok, sounds good then
| |
107 SequenceChecker sequence_checker_; | 136 SequenceChecker sequence_checker_; |
108 bool is_valid_; | 137 #endif |
109 }; | 138 }; |
110 | 139 |
111 WeakReference(); | 140 WeakReference(); |
112 explicit WeakReference(const Flag* flag); | 141 explicit WeakReference(const Flag* flag); |
113 ~WeakReference(); | 142 ~WeakReference(); |
114 | 143 |
115 WeakReference(WeakReference&& other); | 144 WeakReference(WeakReference&& other); |
116 WeakReference(const WeakReference& other); | 145 WeakReference(const WeakReference& other); |
117 WeakReference& operator=(WeakReference&& other) = default; | 146 WeakReference& operator=(WeakReference&& other) = default; |
118 WeakReference& operator=(const WeakReference& other) = default; | 147 WeakReference& operator=(const WeakReference& other) = default; |
119 | 148 |
120 bool is_valid() const; | 149 uintptr_t is_valid() const { return flag_->IsValid(); } |
121 | 150 |
122 private: | 151 private: |
152 // Note: To avoid null-checks, flag_ always points to either Flag::nullFlag() | |
153 // or some other object. | |
123 scoped_refptr<const Flag> flag_; | 154 scoped_refptr<const Flag> flag_; |
124 }; | 155 }; |
125 | 156 |
126 class BASE_EXPORT WeakReferenceOwner { | 157 class BASE_EXPORT WeakReferenceOwner { |
127 public: | 158 public: |
128 WeakReferenceOwner(); | 159 WeakReferenceOwner(); |
129 ~WeakReferenceOwner(); | 160 ~WeakReferenceOwner(); |
130 | 161 |
131 WeakReference GetRef() const; | 162 WeakReference GetRef() const; |
132 | 163 |
133 bool HasRefs() const { | 164 bool HasRefs() const { return flag_->IsValid() && !flag_->HasOneRef(); } |
134 return flag_.get() && !flag_->HasOneRef(); | |
135 } | |
136 | 165 |
137 void Invalidate(); | 166 void Invalidate(); |
138 | 167 |
139 private: | 168 private: |
140 mutable scoped_refptr<WeakReference::Flag> flag_; | 169 mutable scoped_refptr<WeakReference::Flag> flag_; |
141 }; | 170 }; |
142 | 171 |
143 // This class simplifies the implementation of WeakPtr's type conversion | 172 // This class simplifies the implementation of WeakPtr's type conversion |
144 // constructor by avoiding the need for a public accessor for ref_. A | 173 // constructor by avoiding the need for a public accessor for ref_. A |
145 // WeakPtr<T> cannot access the private members of WeakPtr<U>, so this | 174 // WeakPtr<T> cannot access the private members of WeakPtr<U>, so this |
146 // base class gives us a way to access ref_ in a protected fashion. | 175 // base class gives us a way to access ref_ in a protected fashion. |
147 class BASE_EXPORT WeakPtrBase { | 176 class BASE_EXPORT WeakPtrBase { |
148 public: | 177 public: |
149 WeakPtrBase(); | 178 WeakPtrBase(); |
150 ~WeakPtrBase(); | 179 ~WeakPtrBase(); |
151 | 180 |
152 WeakPtrBase(const WeakPtrBase& other) = default; | 181 WeakPtrBase(const WeakPtrBase& other) = default; |
153 WeakPtrBase(WeakPtrBase&& other) = default; | 182 WeakPtrBase(WeakPtrBase&& other) = default; |
154 WeakPtrBase& operator=(const WeakPtrBase& other) = default; | 183 WeakPtrBase& operator=(const WeakPtrBase& other) = default; |
155 WeakPtrBase& operator=(WeakPtrBase&& other) = default; | 184 WeakPtrBase& operator=(WeakPtrBase&& other) = default; |
156 | 185 |
157 protected: | 186 protected: |
158 explicit WeakPtrBase(const WeakReference& ref); | 187 explicit WeakPtrBase(const WeakReference& ref); |
159 | 188 |
160 WeakReference ref_; | 189 WeakReference ref_; |
190 | |
191 // This pointer is only valid when ref_.is_valid() is true. Otherwise, its | |
192 // value is undefined (as opposed to nullptr). | |
193 uintptr_t ptr_; | |
Nico
2017/06/28 14:54:10
Moving this to the base class also feels kind of u
hans
2017/06/28 20:37:35
Done. Splitting this out.
| |
161 }; | 194 }; |
162 | 195 |
163 // This class provides a common implementation of common functions that would | 196 // This class provides a common implementation of common functions that would |
164 // otherwise get instantiated separately for each distinct instantiation of | 197 // otherwise get instantiated separately for each distinct instantiation of |
165 // SupportsWeakPtr<>. | 198 // SupportsWeakPtr<>. |
166 class SupportsWeakPtrBase { | 199 class SupportsWeakPtrBase { |
167 public: | 200 public: |
168 // A safe static downcast of a WeakPtr<Base> to WeakPtr<Derived>. This | 201 // A safe static downcast of a WeakPtr<Base> to WeakPtr<Derived>. This |
169 // conversion will only compile if there is exists a Base which inherits | 202 // conversion will only compile if there is exists a Base which inherits |
170 // from SupportsWeakPtr<Base>. See base::AsWeakPtr() below for a helper | 203 // from SupportsWeakPtr<Base>. See base::AsWeakPtr() below for a helper |
171 // function that makes calling this easier. | 204 // function that makes calling this easier. |
172 template<typename Derived> | 205 template<typename Derived> |
173 static WeakPtr<Derived> StaticAsWeakPtr(Derived* t) { | 206 static WeakPtr<Derived> StaticAsWeakPtr(Derived* t) { |
174 static_assert( | 207 static_assert( |
175 std::is_base_of<internal::SupportsWeakPtrBase, Derived>::value, | 208 std::is_base_of<internal::SupportsWeakPtrBase, Derived>::value, |
176 "AsWeakPtr argument must inherit from SupportsWeakPtr"); | 209 "AsWeakPtr argument must inherit from SupportsWeakPtr"); |
177 return AsWeakPtrImpl<Derived>(t, *t); | 210 return AsWeakPtrImpl<Derived>(t, *t); |
178 } | 211 } |
179 | 212 |
180 private: | 213 private: |
181 // This template function uses type inference to find a Base of Derived | 214 // This template function uses type inference to find a Base of Derived |
182 // which is an instance of SupportsWeakPtr<Base>. We can then safely | 215 // which is an instance of SupportsWeakPtr<Base>. We can then safely |
183 // static_cast the Base* to a Derived*. | 216 // static_cast the Base* to a Derived*. |
184 template <typename Derived, typename Base> | 217 template <typename Derived, typename Base> |
185 static WeakPtr<Derived> AsWeakPtrImpl( | 218 static WeakPtr<Derived> AsWeakPtrImpl( |
186 Derived* t, const SupportsWeakPtr<Base>&) { | 219 Derived* t, const SupportsWeakPtr<Base>&) { |
187 WeakPtr<Base> ptr = t->Base::AsWeakPtr(); | 220 WeakPtr<Base> ptr = t->Base::AsWeakPtr(); |
188 return WeakPtr<Derived>(ptr.ref_, static_cast<Derived*>(ptr.ptr_)); | 221 return WeakPtr<Derived>( |
222 ptr.ref_, static_cast<Derived*>(reinterpret_cast<Base*>(ptr.ptr_))); | |
189 } | 223 } |
190 }; | 224 }; |
191 | 225 |
192 } // namespace internal | 226 } // namespace internal |
193 | 227 |
194 template <typename T> class WeakPtrFactory; | 228 template <typename T> class WeakPtrFactory; |
195 | 229 |
196 // The WeakPtr class holds a weak reference to |T*|. | 230 // The WeakPtr class holds a weak reference to |T*|. |
197 // | 231 // |
198 // This class is designed to be used like a normal pointer. You should always | 232 // This class is designed to be used like a normal pointer. You should always |
199 // null-test an object of this class before using it or invoking a method that | 233 // null-test an object of this class before using it or invoking a method that |
200 // may result in the underlying object being destroyed. | 234 // may result in the underlying object being destroyed. |
201 // | 235 // |
202 // EXAMPLE: | 236 // EXAMPLE: |
203 // | 237 // |
204 // class Foo { ... }; | 238 // class Foo { ... }; |
205 // WeakPtr<Foo> foo; | 239 // WeakPtr<Foo> foo; |
206 // if (foo) | 240 // if (foo) |
207 // foo->method(); | 241 // foo->method(); |
208 // | 242 // |
209 template <typename T> | 243 template <typename T> |
210 class WeakPtr : public internal::WeakPtrBase { | 244 class WeakPtr : public internal::WeakPtrBase { |
211 public: | 245 public: |
212 WeakPtr() : ptr_(nullptr) {} | 246 WeakPtr() {} |
213 | 247 |
214 WeakPtr(std::nullptr_t) : ptr_(nullptr) {} | 248 WeakPtr(std::nullptr_t) {} |
215 | 249 |
216 // Allow conversion from U to T provided U "is a" T. Note that this | 250 // Allow conversion from U to T provided U "is a" T. Note that this |
217 // is separate from the (implicit) copy and move constructors. | 251 // is separate from the (implicit) copy and move constructors. |
218 template <typename U> | 252 template <typename U> |
219 WeakPtr(const WeakPtr<U>& other) : WeakPtrBase(other), ptr_(other.ptr_) { | 253 WeakPtr(const WeakPtr<U>& other) : WeakPtrBase(other) { |
254 static_assert(std::is_base_of<T, U>::value, | |
255 "other must be a subclass of T"); | |
220 } | 256 } |
221 template <typename U> | 257 template <typename U> |
222 WeakPtr(WeakPtr<U>&& other) | 258 WeakPtr(WeakPtr<U>&& other) : WeakPtrBase(std::move(other)) { |
223 : WeakPtrBase(std::move(other)), ptr_(other.ptr_) {} | 259 static_assert(std::is_base_of<T, U>::value, |
260 "other must be a subclass of T"); | |
261 } | |
224 | 262 |
225 T* get() const { return ref_.is_valid() ? ptr_ : nullptr; } | 263 T* get() const { return reinterpret_cast<T*>(ref_.is_valid() & ptr_); } |
Nico
2017/06/28 14:54:09
Since this is so unusual, I'd probably add `// Int
hans
2017/06/28 20:37:35
Done.
| |
226 | 264 |
227 T& operator*() const { | 265 T& operator*() const { |
228 DCHECK(get() != nullptr); | 266 DCHECK(get() != nullptr); |
229 return *get(); | 267 return *get(); |
230 } | 268 } |
231 T* operator->() const { | 269 T* operator->() const { |
232 DCHECK(get() != nullptr); | 270 DCHECK(get() != nullptr); |
233 return get(); | 271 return get(); |
234 } | 272 } |
235 | 273 |
236 void reset() { | 274 void reset() { |
237 ref_ = internal::WeakReference(); | 275 ref_ = internal::WeakReference(); |
238 ptr_ = nullptr; | 276 ptr_ = 0; |
239 } | 277 } |
240 | 278 |
241 // Allow conditionals to test validity, e.g. if (weak_ptr) {...}; | 279 // Allow conditionals to test validity, e.g. if (weak_ptr) {...}; |
242 explicit operator bool() const { return get() != nullptr; } | 280 explicit operator bool() const { return get() != nullptr; } |
243 | 281 |
244 private: | 282 private: |
245 friend class internal::SupportsWeakPtrBase; | 283 friend class internal::SupportsWeakPtrBase; |
246 template <typename U> friend class WeakPtr; | 284 template <typename U> friend class WeakPtr; |
247 friend class SupportsWeakPtr<T>; | 285 friend class SupportsWeakPtr<T>; |
248 friend class WeakPtrFactory<T>; | 286 friend class WeakPtrFactory<T>; |
249 | 287 |
250 WeakPtr(const internal::WeakReference& ref, T* ptr) | 288 WeakPtr(const internal::WeakReference& ref, T* ptr) : WeakPtrBase(ref) { |
251 : WeakPtrBase(ref), | 289 ptr_ = reinterpret_cast<uintptr_t>(ptr); |
252 ptr_(ptr) { | |
253 } | 290 } |
254 | |
255 // This pointer is only valid when ref_.is_valid() is true. Otherwise, its | |
256 // value is undefined (as opposed to nullptr). | |
257 T* ptr_; | |
258 }; | 291 }; |
259 | 292 |
260 // Allow callers to compare WeakPtrs against nullptr to test validity. | 293 // Allow callers to compare WeakPtrs against nullptr to test validity. |
261 template <class T> | 294 template <class T> |
262 bool operator!=(const WeakPtr<T>& weak_ptr, std::nullptr_t) { | 295 bool operator!=(const WeakPtr<T>& weak_ptr, std::nullptr_t) { |
263 return !(weak_ptr == nullptr); | 296 return !(weak_ptr == nullptr); |
264 } | 297 } |
265 template <class T> | 298 template <class T> |
266 bool operator!=(std::nullptr_t, const WeakPtr<T>& weak_ptr) { | 299 bool operator!=(std::nullptr_t, const WeakPtr<T>& weak_ptr) { |
267 return weak_ptr != nullptr; | 300 return weak_ptr != nullptr; |
268 } | 301 } |
269 template <class T> | 302 template <class T> |
270 bool operator==(const WeakPtr<T>& weak_ptr, std::nullptr_t) { | 303 bool operator==(const WeakPtr<T>& weak_ptr, std::nullptr_t) { |
271 return weak_ptr.get() == nullptr; | 304 return weak_ptr.get() == nullptr; |
272 } | 305 } |
273 template <class T> | 306 template <class T> |
274 bool operator==(std::nullptr_t, const WeakPtr<T>& weak_ptr) { | 307 bool operator==(std::nullptr_t, const WeakPtr<T>& weak_ptr) { |
275 return weak_ptr == nullptr; | 308 return weak_ptr == nullptr; |
276 } | 309 } |
277 | 310 |
311 namespace internal { | |
312 class BASE_EXPORT WeakPtrFactoryBase { | |
313 protected: | |
314 WeakPtrFactoryBase(uintptr_t ptr); | |
315 ~WeakPtrFactoryBase(); | |
316 internal::WeakReferenceOwner weak_reference_owner_; | |
317 uintptr_t ptr_; | |
318 }; | |
319 } // namespace internal | |
320 | |
278 // A class may be composed of a WeakPtrFactory and thereby | 321 // A class may be composed of a WeakPtrFactory and thereby |
279 // control how it exposes weak pointers to itself. This is helpful if you only | 322 // control how it exposes weak pointers to itself. This is helpful if you only |
280 // need weak pointers within the implementation of a class. This class is also | 323 // need weak pointers within the implementation of a class. This class is also |
281 // useful when working with primitive types. For example, you could have a | 324 // useful when working with primitive types. For example, you could have a |
282 // WeakPtrFactory<bool> that is used to pass around a weak reference to a bool. | 325 // WeakPtrFactory<bool> that is used to pass around a weak reference to a bool. |
283 template <class T> | 326 template <class T> |
284 class WeakPtrFactory { | 327 class WeakPtrFactory : public internal::WeakPtrFactoryBase { |
285 public: | 328 public: |
286 explicit WeakPtrFactory(T* ptr) : ptr_(ptr) { | 329 explicit WeakPtrFactory(T* ptr) |
287 } | 330 : WeakPtrFactoryBase(reinterpret_cast<uintptr_t>(ptr)) {} |
288 | 331 |
289 ~WeakPtrFactory() { ptr_ = nullptr; } | 332 ~WeakPtrFactory() {} |
290 | 333 |
291 WeakPtr<T> GetWeakPtr() { | 334 WeakPtr<T> GetWeakPtr() { |
292 DCHECK(ptr_); | 335 DCHECK(ptr_); |
293 return WeakPtr<T>(weak_reference_owner_.GetRef(), ptr_); | 336 return WeakPtr<T>(weak_reference_owner_.GetRef(), |
337 reinterpret_cast<T*>(ptr_)); | |
294 } | 338 } |
295 | 339 |
296 // Call this method to invalidate all existing weak pointers. | 340 // Call this method to invalidate all existing weak pointers. |
297 void InvalidateWeakPtrs() { | 341 void InvalidateWeakPtrs() { |
298 DCHECK(ptr_); | 342 DCHECK(ptr_); |
299 weak_reference_owner_.Invalidate(); | 343 weak_reference_owner_.Invalidate(); |
300 } | 344 } |
301 | 345 |
302 // Call this method to determine if any weak pointers exist. | 346 // Call this method to determine if any weak pointers exist. |
303 bool HasWeakPtrs() const { | 347 bool HasWeakPtrs() const { |
304 DCHECK(ptr_); | 348 DCHECK(ptr_); |
305 return weak_reference_owner_.HasRefs(); | 349 return weak_reference_owner_.HasRefs(); |
306 } | 350 } |
307 | 351 |
308 private: | 352 private: |
309 internal::WeakReferenceOwner weak_reference_owner_; | |
310 T* ptr_; | |
311 DISALLOW_IMPLICIT_CONSTRUCTORS(WeakPtrFactory); | 353 DISALLOW_IMPLICIT_CONSTRUCTORS(WeakPtrFactory); |
312 }; | 354 }; |
313 | 355 |
314 // A class may extend from SupportsWeakPtr to let others take weak pointers to | 356 // A class may extend from SupportsWeakPtr to let others take weak pointers to |
315 // it. This avoids the class itself implementing boilerplate to dispense weak | 357 // it. This avoids the class itself implementing boilerplate to dispense weak |
316 // pointers. However, since SupportsWeakPtr's destructor won't invalidate | 358 // pointers. However, since SupportsWeakPtr's destructor won't invalidate |
317 // weak pointers to the class until after the derived class' members have been | 359 // weak pointers to the class until after the derived class' members have been |
318 // destroyed, its use can lead to subtle use-after-destroy issues. | 360 // destroyed, its use can lead to subtle use-after-destroy issues. |
319 template <class T> | 361 template <class T> |
320 class SupportsWeakPtr : public internal::SupportsWeakPtrBase { | 362 class SupportsWeakPtr : public internal::SupportsWeakPtrBase { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
352 // base::WeakPtr<Derived> ptr = derived.AsWeakPtr(); // Fails. | 394 // base::WeakPtr<Derived> ptr = derived.AsWeakPtr(); // Fails. |
353 | 395 |
354 template <typename Derived> | 396 template <typename Derived> |
355 WeakPtr<Derived> AsWeakPtr(Derived* t) { | 397 WeakPtr<Derived> AsWeakPtr(Derived* t) { |
356 return internal::SupportsWeakPtrBase::StaticAsWeakPtr<Derived>(t); | 398 return internal::SupportsWeakPtrBase::StaticAsWeakPtr<Derived>(t); |
357 } | 399 } |
358 | 400 |
359 } // namespace base | 401 } // namespace base |
360 | 402 |
361 #endif // BASE_MEMORY_WEAK_PTR_H_ | 403 #endif // BASE_MEMORY_WEAK_PTR_H_ |
OLD | NEW |