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 |
3 | // found in the LICENSE file. |
4 | |
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 |
7 | // owner, at any time, most commonly when the object is about to be deleted. |
8 | |
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 |
11 | // object vanishing and e.g. tasks posted to it being silently dropped. |
12 | // Reference-counting such an object would complicate the ownership graph and |
13 | // make it harder to reason about the object's lifetime. |
14 | |
15 | // EXAMPLE: |
16 | // |
17 | // class Controller { |
18 | // public: |
19 | // Controller() : weak_factory_(this) {} |
20 | // void SpawnWorker() { Worker::StartNew(weak_factory_.GetWeakPtr()); } |
21 | // void WorkComplete(const Result& result) { ... } |
22 | // private: |
23 | // // Member variables should appear before the WeakPtrFactory, to ensure |
24 | // // that any WeakPtrs to Controller are invalidated before its members |
25 | // // variable's destructors are executed, rendering them invalid. |
26 | // WeakPtrFactory<Controller> weak_factory_; |
27 | // }; |
28 | // |
29 | // class Worker { |
30 | // public: |
31 | // static void StartNew(const WeakPtr<Controller>& controller) { |
32 | // Worker* worker = new Worker(controller); |
33 | // // Kick off asynchronous processing... |
34 | // } |
35 | // private: |
36 | // Worker(const WeakPtr<Controller>& controller) |
37 | // : controller_(controller) {} |
38 | // void DidCompleteAsynchronousProcessing(const Result& result) { |
39 | // if (controller_) |
40 | // controller_->WorkComplete(result); |
41 | // } |
42 | // WeakPtr<Controller> controller_; |
43 | // }; |
44 | // |
45 | // With this implementation a caller may use SpawnWorker() to dispatch multiple |
46 | // Workers and subsequently delete the Controller, without waiting for all |
47 | // Workers to have completed. |
48 | |
49 | // ------------------------- IMPORTANT: Thread-safety ------------------------- |
50 | |
51 | // Weak pointers may be passed safely between sequences, but must always be |
52 | // dereferenced and invalidated on the same SequencedTaskRunner otherwise |
53 | // checking the pointer would be racey. |
54 | // |
55 | // To ensure correct use, the first time a WeakPtr issued by a WeakPtrFactory |
56 | // is dereferenced, the factory and its WeakPtrs become bound to the calling |
57 | // sequence or current SequencedWorkerPool token, and cannot be dereferenced or |
58 | // invalidated on any other task runner. Bound WeakPtrs can still be handed |
59 | // off to other task runners, e.g. to use to post tasks back to object on the |
60 | // bound sequence. |
61 | // |
62 | // If all WeakPtr objects are destroyed or invalidated then the factory is |
63 | // unbound from the SequencedTaskRunner/Thread. The WeakPtrFactory may then be |
64 | // destroyed, or new WeakPtr objects may be used, from a different sequence. |
65 | // |
66 | // Thus, at least one WeakPtr object must exist and have been dereferenced on |
67 | // the correct sequence to enforce that other WeakPtr objects will enforce they |
68 | // are used on the desired sequence. |
69 | |
70 | #ifndef BASE_MEMORY_WEAK_PTR_H_ |
71 | #define BASE_MEMORY_WEAK_PTR_H_ |
72 | |
73 | #include <cstddef> |
74 | #include <type_traits> |
75 | |
76 | #include "base/base_export.h" |
77 | #include "base/logging.h" |
78 | #include "base/macros.h" |
79 | #include "base/memory/ref_counted.h" |
80 | #include "base/sequence_checker.h" |
81 | #include "base/synchronization/atomic_flag.h" |
82 | |
83 | namespace base { |
84 | |
85 | template <typename T> class SupportsWeakPtr; |
86 | template <typename T> class WeakPtr; |
87 | |
88 | namespace internal { |
89 | // These classes are part of the WeakPtr implementation. |
90 | // DO NOT USE THESE CLASSES DIRECTLY YOURSELF. |
91 | |
92 | class BASE_EXPORT WeakReference { |
93 | public: |
94 | // Although Flag is bound to a specific SequencedTaskRunner, it may be |
95 | // deleted from another via base::WeakPtr::~WeakPtr(). |
96 | class BASE_EXPORT Flag : public RefCountedThreadSafe<Flag> { |
97 | public: |
98 | Flag(); |
99 | |
100 | void Invalidate(); |
101 | bool IsValid() const; |
102 | |
103 | bool MaybeValid() const; |
104 | |
105 | void DetachFromSequence(); |
106 | |
107 | private: |
108 | friend class base::RefCountedThreadSafe<Flag>; |
109 | |
110 | ~Flag(); |
111 | |
112 | SEQUENCE_CHECKER(sequence_checker_); |
113 | AtomicFlag invalidated_; |
114 | }; |
115 | |
116 | WeakReference(); |
117 | explicit WeakReference(const scoped_refptr<Flag>& flag); |
118 | ~WeakReference(); |
119 | |
120 | WeakReference(WeakReference&& other); |
121 | WeakReference(const WeakReference& other); |
122 | WeakReference& operator=(WeakReference&& other) = default; |
123 | WeakReference& operator=(const WeakReference& other) = default; |
124 | |
125 | bool IsValid() const; |
126 | bool MaybeValid() const; |
127 | |
128 | private: |
129 | scoped_refptr<const Flag> flag_; |
130 | }; |
131 | |
132 | class BASE_EXPORT WeakReferenceOwner { |
133 | public: |
134 | WeakReferenceOwner(); |
135 | ~WeakReferenceOwner(); |
136 | WeakReferenceOwner(WeakReferenceOwner&& other) = default; |
137 | WeakReferenceOwner(const WeakReferenceOwner& other) = default; |
138 | WeakReferenceOwner& operator=(WeakReferenceOwner&& other) = default; |
139 | WeakReferenceOwner& operator=(const WeakReferenceOwner& other) = default; |
140 | |
141 | WeakReference GetRef() const; |
142 | |
143 | bool HasRefs() const { return !flag_->HasOneRef(); } |
144 | |
145 | void Invalidate(); |
146 | |
147 | private: |
148 | mutable scoped_refptr<WeakReference::Flag> flag_; |
149 | }; |
150 | |
151 | // This class simplifies the implementation of WeakPtr's type conversion |
152 | // constructor by avoiding the need for a public accessor for ref_. A |
153 | // WeakPtr<T> cannot access the private members of WeakPtr<U>, so this |
154 | // base class gives us a way to access ref_ in a protected fashion. |
155 | class BASE_EXPORT WeakPtrBase { |
156 | public: |
157 | WeakPtrBase(); |
158 | ~WeakPtrBase(); |
159 | |
160 | WeakPtrBase(const WeakPtrBase& other) = default; |
161 | WeakPtrBase(WeakPtrBase&& other) = default; |
162 | WeakPtrBase& operator=(const WeakPtrBase& other) = default; |
163 | WeakPtrBase& operator=(WeakPtrBase&& other) = default; |
164 | |
165 | void reset() { |
166 | ref_ = internal::WeakReference(); |
167 | ptr_ = 0; |
168 | } |
169 | |
170 | protected: |
171 | WeakPtrBase(const WeakReference& ref, uintptr_t ptr); |
172 | |
173 | WeakReference ref_; |
174 | |
175 | // This pointer is only valid when ref_.is_valid() is true. Otherwise, its |
176 | // value is undefined (as opposed to nullptr). |
177 | uintptr_t ptr_; |
178 | }; |
179 | |
180 | // This class provides a common implementation of common functions that would |
181 | // otherwise get instantiated separately for each distinct instantiation of |
182 | // SupportsWeakPtr<>. |
183 | class SupportsWeakPtrBase { |
184 | public: |
185 | // A safe static downcast of a WeakPtr<Base> to WeakPtr<Derived>. This |
186 | // conversion will only compile if there is exists a Base which inherits |
187 | // from SupportsWeakPtr<Base>. See base::AsWeakPtr() below for a helper |
188 | // function that makes calling this easier. |
189 | // |
190 | // Precondition: t != nullptr |
191 | template<typename Derived> |
192 | static WeakPtr<Derived> StaticAsWeakPtr(Derived* t) { |
193 | static_assert( |
194 | std::is_base_of<internal::SupportsWeakPtrBase, Derived>::value, |
195 | "AsWeakPtr argument must inherit from SupportsWeakPtr" ); |
196 | return AsWeakPtrImpl<Derived>(t); |
197 | } |
198 | |
199 | private: |
200 | // This template function uses type inference to find a Base of Derived |
201 | // which is an instance of SupportsWeakPtr<Base>. We can then safely |
202 | // static_cast the Base* to a Derived*. |
203 | template <typename Derived, typename Base> |
204 | static WeakPtr<Derived> AsWeakPtrImpl(SupportsWeakPtr<Base>* t) { |
205 | WeakPtr<Base> ptr = t->AsWeakPtr(); |
206 | return WeakPtr<Derived>( |
207 | ptr.ref_, static_cast<Derived*>(reinterpret_cast<Base*>(ptr.ptr_))); |
208 | } |
209 | }; |
210 | |
211 | } // namespace internal |
212 | |
213 | template <typename T> class WeakPtrFactory; |
214 | |
215 | // The WeakPtr class holds a weak reference to |T*|. |
216 | // |
217 | // This class is designed to be used like a normal pointer. You should always |
218 | // null-test an object of this class before using it or invoking a method that |
219 | // may result in the underlying object being destroyed. |
220 | // |
221 | // EXAMPLE: |
222 | // |
223 | // class Foo { ... }; |
224 | // WeakPtr<Foo> foo; |
225 | // if (foo) |
226 | // foo->method(); |
227 | // |
228 | template <typename T> |
229 | class WeakPtr : public internal::WeakPtrBase { |
230 | public: |
231 | WeakPtr() = default; |
232 | WeakPtr(std::nullptr_t) {} |
233 | |
234 | // Allow conversion from U to T provided U "is a" T. Note that this |
235 | // is separate from the (implicit) copy and move constructors. |
236 | template <typename U> |
237 | WeakPtr(const WeakPtr<U>& other) : WeakPtrBase(other) { |
238 | // Need to cast from U* to T* to do pointer adjustment in case of multiple |
239 | // inheritance. This also enforces the "U is a T" rule. |
240 | T* t = reinterpret_cast<U*>(other.ptr_); |
241 | ptr_ = reinterpret_cast<uintptr_t>(t); |
242 | } |
243 | template <typename U> |
244 | WeakPtr(WeakPtr<U>&& other) : WeakPtrBase(std::move(other)) { |
245 | // Need to cast from U* to T* to do pointer adjustment in case of multiple |
246 | // inheritance. This also enforces the "U is a T" rule. |
247 | T* t = reinterpret_cast<U*>(other.ptr_); |
248 | ptr_ = reinterpret_cast<uintptr_t>(t); |
249 | } |
250 | |
251 | T* get() const { |
252 | return ref_.IsValid() ? reinterpret_cast<T*>(ptr_) : nullptr; |
253 | } |
254 | |
255 | T& operator*() const { |
256 | DCHECK(get() != nullptr); |
257 | return *get(); |
258 | } |
259 | T* operator->() const { |
260 | DCHECK(get() != nullptr); |
261 | return get(); |
262 | } |
263 | |
264 | // Allow conditionals to test validity, e.g. if (weak_ptr) {...}; |
265 | explicit operator bool() const { return get() != nullptr; } |
266 | |
267 | // Returns false if the WeakPtr is confirmed to be invalid. This call is safe |
268 | // to make from any thread, e.g. to optimize away unnecessary work, but |
269 | // operator bool() must always be called, on the correct sequence, before |
270 | // actually using the pointer. |
271 | // |
272 | // Warning: as with any object, this call is only thread-safe if the WeakPtr |
273 | // instance isn't being re-assigned or reset() racily with this call. |
274 | bool MaybeValid() const { return ref_.MaybeValid(); } |
275 | |
276 | // Returns whether the object |this| points to has been invalidated. This can |
277 | // be used to distinguish a WeakPtr to a destroyed object from one that has |
278 | // been explicitly set to null. |
279 | bool WasInvalidated() const { return ptr_ && !ref_.IsValid(); } |
280 | |
281 | private: |
282 | friend class internal::SupportsWeakPtrBase; |
283 | template <typename U> friend class WeakPtr; |
284 | friend class SupportsWeakPtr<T>; |
285 | friend class WeakPtrFactory<T>; |
286 | |
287 | WeakPtr(const internal::WeakReference& ref, T* ptr) |
288 | : WeakPtrBase(ref, reinterpret_cast<uintptr_t>(ptr)) {} |
289 | }; |
290 | |
291 | // Allow callers to compare WeakPtrs against nullptr to test validity. |
292 | template <class T> |
293 | bool operator!=(const WeakPtr<T>& weak_ptr, std::nullptr_t) { |
294 | return !(weak_ptr == nullptr); |
295 | } |
296 | template <class T> |
297 | bool operator!=(std::nullptr_t, const WeakPtr<T>& weak_ptr) { |
298 | return weak_ptr != nullptr; |
299 | } |
300 | template <class T> |
301 | bool operator==(const WeakPtr<T>& weak_ptr, std::nullptr_t) { |
302 | return weak_ptr.get() == nullptr; |
303 | } |
304 | template <class T> |
305 | bool operator==(std::nullptr_t, const WeakPtr<T>& weak_ptr) { |
306 | return weak_ptr == nullptr; |
307 | } |
308 | |
309 | namespace internal { |
310 | class BASE_EXPORT WeakPtrFactoryBase { |
311 | protected: |
312 | WeakPtrFactoryBase(uintptr_t ptr); |
313 | ~WeakPtrFactoryBase(); |
314 | internal::WeakReferenceOwner weak_reference_owner_; |
315 | uintptr_t ptr_; |
316 | }; |
317 | } // namespace internal |
318 | |
319 | // A class may be composed of a WeakPtrFactory and thereby |
320 | // control how it exposes weak pointers to itself. This is helpful if you only |
321 | // need weak pointers within the implementation of a class. This class is also |
322 | // useful when working with primitive types. For example, you could have a |
323 | // WeakPtrFactory<bool> that is used to pass around a weak reference to a bool. |
324 | template <class T> |
325 | class WeakPtrFactory : public internal::WeakPtrFactoryBase { |
326 | public: |
327 | explicit WeakPtrFactory(T* ptr) |
328 | : WeakPtrFactoryBase(reinterpret_cast<uintptr_t>(ptr)) {} |
329 | |
330 | ~WeakPtrFactory() = default; |
331 | WeakPtrFactory(WeakPtrFactory&&) = default; |
332 | WeakPtrFactory& operator=(WeakPtrFactory&&) = default; |
333 | |
334 | WeakPtr<T> GetWeakPtr() { |
335 | return WeakPtr<T>(weak_reference_owner_.GetRef(), |
336 | reinterpret_cast<T*>(ptr_)); |
337 | } |
338 | |
339 | // Call this method to invalidate all existing weak pointers. |
340 | void InvalidateWeakPtrs() { |
341 | DCHECK(ptr_); |
342 | weak_reference_owner_.Invalidate(); |
343 | } |
344 | |
345 | // Call this method to determine if any weak pointers exist. |
346 | bool HasWeakPtrs() const { |
347 | DCHECK(ptr_); |
348 | return weak_reference_owner_.HasRefs(); |
349 | } |
350 | |
351 | private: |
352 | DISALLOW_IMPLICIT_CONSTRUCTORS(WeakPtrFactory); |
353 | }; |
354 | |
355 | // A class may extend from SupportsWeakPtr to let others take weak pointers to |
356 | // it. This avoids the class itself implementing boilerplate to dispense weak |
357 | // pointers. However, since SupportsWeakPtr's destructor won't invalidate |
358 | // weak pointers to the class until after the derived class' members have been |
359 | // destroyed, its use can lead to subtle use-after-destroy issues. |
360 | template <class T> |
361 | class SupportsWeakPtr : public internal::SupportsWeakPtrBase { |
362 | public: |
363 | SupportsWeakPtr() = default; |
364 | |
365 | WeakPtr<T> AsWeakPtr() { |
366 | return WeakPtr<T>(weak_reference_owner_.GetRef(), static_cast<T*>(this)); |
367 | } |
368 | |
369 | protected: |
370 | ~SupportsWeakPtr() = default; |
371 | |
372 | private: |
373 | internal::WeakReferenceOwner weak_reference_owner_; |
374 | DISALLOW_COPY_AND_ASSIGN(SupportsWeakPtr); |
375 | }; |
376 | |
377 | // Helper function that uses type deduction to safely return a WeakPtr<Derived> |
378 | // when Derived doesn't directly extend SupportsWeakPtr<Derived>, instead it |
379 | // extends a Base that extends SupportsWeakPtr<Base>. |
380 | // |
381 | // EXAMPLE: |
382 | // class Base : public base::SupportsWeakPtr<Producer> {}; |
383 | // class Derived : public Base {}; |
384 | // |
385 | // Derived derived; |
386 | // base::WeakPtr<Derived> ptr = base::AsWeakPtr(&derived); |
387 | // |
388 | // Note that the following doesn't work (invalid type conversion) since |
389 | // Derived::AsWeakPtr() is WeakPtr<Base> SupportsWeakPtr<Base>::AsWeakPtr(), |
390 | // and there's no way to safely cast WeakPtr<Base> to WeakPtr<Derived> at |
391 | // the caller. |
392 | // |
393 | // base::WeakPtr<Derived> ptr = derived.AsWeakPtr(); // Fails. |
394 | |
395 | template <typename Derived> |
396 | WeakPtr<Derived> AsWeakPtr(Derived* t) { |
397 | return internal::SupportsWeakPtrBase::StaticAsWeakPtr<Derived>(t); |
398 | } |
399 | |
400 | } // namespace base |
401 | |
402 | #endif // BASE_MEMORY_WEAK_PTR_H_ |
403 | |