blob: 250ba23f5c001f5368f086c8a684d2b853970880 [file] [log] [blame]
Avi Drissmane4622aa2022-09-08 20:36:061// Copyright 2012 The Chromium Authors
[email protected]3125d6462009-09-01 20:50:172// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]2c691392013-04-25 20:47:185// Weak pointers are pointers to an object that do not affect its lifetime,
dchengefeb19b2016-04-05 20:07:406// and which may be invalidated (i.e. reset to nullptr) by the object, or its
[email protected]2c691392013-04-25 20:47:187// 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
[email protected]3125d6462009-09-01 20:50:1715// EXAMPLE:
16//
[email protected]2c691392013-04-25 20:47:1817// class Controller {
[email protected]3125d6462009-09-01 20:50:1718// public:
[email protected]2c691392013-04-25 20:47:1819// void SpawnWorker() { Worker::StartNew(weak_factory_.GetWeakPtr()); }
[email protected]3125d6462009-09-01 20:50:1720// void WorkComplete(const Result& result) { ... }
[email protected]2c691392013-04-25 20:47:1821// private:
[email protected]ed3f67342013-05-29 08:04:3222// // Member variables should appear before the WeakPtrFactory, to ensure
23// // that any WeakPtrs to Controller are invalidated before its members
24// // variable's destructors are executed, rendering them invalid.
Jeremy Roman0dd0b2f2019-07-16 21:00:4325// WeakPtrFactory<Controller> weak_factory_{this};
[email protected]3125d6462009-09-01 20:50:1726// };
27//
28// class Worker {
29// public:
Daniel Hosseinianfff4da52021-01-27 22:13:0830// static void StartNew(WeakPtr<Controller> controller) {
danakjb57ac1d2021-12-03 21:52:4931// // Move WeakPtr when possible to avoid atomic refcounting churn on its
32// // internal state.
Daniel Hosseinianfff4da52021-01-27 22:13:0833// Worker* worker = new Worker(std::move(controller));
[email protected]3125d6462009-09-01 20:50:1734// // Kick off asynchronous processing...
35// }
36// private:
Daniel Hosseinianfff4da52021-01-27 22:13:0837// Worker(WeakPtr<Controller> controller)
38// : controller_(std::move(controller)) {}
[email protected]3125d6462009-09-01 20:50:1739// void DidCompleteAsynchronousProcessing(const Result& result) {
40// if (controller_)
41// controller_->WorkComplete(result);
42// }
43// WeakPtr<Controller> controller_;
44// };
45//
[email protected]2c691392013-04-25 20:47:1846// With this implementation a caller may use SpawnWorker() to dispatch multiple
47// Workers and subsequently delete the Controller, without waiting for all
48// Workers to have completed.
49
50// ------------------------- IMPORTANT: Thread-safety -------------------------
51
Nicolas Ouellet-payeurff1eab62018-07-19 18:41:5052// Weak pointers may be passed safely between sequences, but must always be
davidbene58877e2014-10-22 18:37:1153// dereferenced and invalidated on the same SequencedTaskRunner otherwise
54// checking the pointer would be racey.
[email protected]ed3f67342013-05-29 08:04:3255//
56// To ensure correct use, the first time a WeakPtr issued by a WeakPtrFactory
57// is dereferenced, the factory and its WeakPtrs become bound to the calling
Nicolas Ouellet-payeurff1eab62018-07-19 18:41:5058// sequence or current SequencedWorkerPool token, and cannot be dereferenced or
davidbene58877e2014-10-22 18:37:1159// invalidated on any other task runner. Bound WeakPtrs can still be handed
60// off to other task runners, e.g. to use to post tasks back to object on the
61// bound sequence.
[email protected]ed3f67342013-05-29 08:04:3262//
scheib3ad03722015-10-05 22:27:4163// If all WeakPtr objects are destroyed or invalidated then the factory is
64// unbound from the SequencedTaskRunner/Thread. The WeakPtrFactory may then be
65// destroyed, or new WeakPtr objects may be used, from a different sequence.
66//
67// Thus, at least one WeakPtr object must exist and have been dereferenced on
Nicolas Ouellet-payeurff1eab62018-07-19 18:41:5068// the correct sequence to enforce that other WeakPtr objects will enforce they
69// are used on the desired sequence.
[email protected]3125d6462009-09-01 20:50:1770
[email protected]3b63f8f42011-03-28 01:54:1571#ifndef BASE_MEMORY_WEAK_PTR_H_
72#define BASE_MEMORY_WEAK_PTR_H_
[email protected]3125d6462009-09-01 20:50:1773
dchengefeb19b2016-04-05 20:07:4074#include <cstddef>
tzik403cb6c2016-03-10 07:17:2575#include <type_traits>
Sumaid Syed22f60eeb2021-08-26 05:16:2676#include <utility>
tzik403cb6c2016-03-10 07:17:2577
[email protected]0bea7252011-08-05 15:34:0078#include "base/base_export.h"
Hans Wennborg7b533712020-06-22 20:52:2779#include "base/check.h"
Lukasz Anforowicz7623e192021-12-02 23:19:3680#include "base/compiler_specific.h"
Igor Bukanov933bad992021-09-10 19:47:2581#include "base/dcheck_is_on.h"
danakjcfcdfb7a2023-02-23 01:05:3582#include "base/memory/raw_ptr.h"
[email protected]3b63f8f42011-03-28 01:54:1583#include "base/memory/ref_counted.h"
[email protected]d52426c2013-07-30 19:26:4084#include "base/sequence_checker.h"
Nicolas Ouellet-payeurff1eab62018-07-19 18:41:5085#include "base/synchronization/atomic_flag.h"
Scott Haseleyda865472023-05-10 19:03:1186#include "base/types/pass_key.h"
[email protected]3125d6462009-09-01 20:50:1787
88namespace base {
89
Scott Haseleyda865472023-05-10 19:03:1190namespace sequence_manager::internal {
91class TaskQueueImpl;
92}
93
danakj45c91782021-09-29 18:23:5794template <typename T>
95class SafeRef;
[email protected]4c44b8442012-06-15 16:36:1296template <typename T> class SupportsWeakPtr;
97template <typename T> class WeakPtr;
98
[email protected]3125d6462009-09-01 20:50:1799namespace internal {
100// These classes are part of the WeakPtr implementation.
101// DO NOT USE THESE CLASSES DIRECTLY YOURSELF.
102
Lukasz Anforowicz7623e192021-12-02 23:19:36103class BASE_EXPORT TRIVIAL_ABI WeakReference {
[email protected]3125d6462009-09-01 20:50:17104 public:
Wezfb4a5282018-05-01 09:02:11105 // Although Flag is bound to a specific SequencedTaskRunner, it may be
106 // deleted from another via base::WeakPtr::~WeakPtr().
[email protected]a827a562014-06-11 00:37:42107 class BASE_EXPORT Flag : public RefCountedThreadSafe<Flag> {
[email protected]d52e97092009-09-17 00:31:09108 public:
[email protected]1edefc42011-08-26 17:32:29109 Flag();
[email protected]59326aac2009-09-25 23:34:34110
hans24046fd2017-06-29 22:07:42111 void Invalidate();
Hans Wennborg4cfa3012017-08-08 03:33:38112 bool IsValid() const;
[email protected]59326aac2009-09-25 23:34:34113
Nicolas Ouellet-payeurff1eab62018-07-19 18:41:50114 bool MaybeValid() const;
115
Igor Bukanov933bad992021-09-10 19:47:25116#if DCHECK_IS_ON()
Wezc5acb1ae2019-02-14 03:09:32117 void DetachFromSequence();
Scott Haseleyda865472023-05-10 19:03:11118 void BindToCurrentSequence();
Igor Bukanov933bad992021-09-10 19:47:25119#endif
Wezc5acb1ae2019-02-14 03:09:32120
[email protected]59326aac2009-09-25 23:34:34121 private:
[email protected]05b1cd612011-04-11 20:47:25122 friend class base::RefCountedThreadSafe<Flag>;
123
124 ~Flag();
125
Nicolas Ouellet-payeurff1eab62018-07-19 18:41:50126 SEQUENCE_CHECKER(sequence_checker_);
127 AtomicFlag invalidated_;
[email protected]3125d6462009-09-01 20:50:17128 };
129
[email protected]3a3d47472010-07-15 21:03:54130 WeakReference();
Wez7eedd9e2018-01-23 00:27:05131 explicit WeakReference(const scoped_refptr<Flag>& flag);
[email protected]201366472010-07-16 17:22:49132 ~WeakReference();
[email protected]59326aac2009-09-25 23:34:34133
mek79016812016-06-24 21:29:04134 WeakReference(const WeakReference& other);
danakjcfcdfb7a2023-02-23 01:05:35135 WeakReference& operator=(const WeakReference& other);
mek79016812016-06-24 21:29:04136
danakjcfcdfb7a2023-02-23 01:05:35137 WeakReference(WeakReference&& other) noexcept;
138 WeakReference& operator=(WeakReference&& other) noexcept;
139
140 void Reset();
141 // Returns whether the WeakReference is valid, meaning the WeakPtrFactory has
142 // not invalidated the pointer. Unlike, RefIsMaybeValid(), this may only be
143 // called from the same sequence as where the WeakPtr was created.
Nicolas Ouellet-payeurff1eab62018-07-19 18:41:50144 bool IsValid() const;
danakjcfcdfb7a2023-02-23 01:05:35145 // Returns false if the WeakReference is confirmed to be invalid. This call is
146 // safe to make from any thread, e.g. to optimize away unnecessary work, but
147 // RefIsValid() must always be called, on the correct sequence, before
148 // actually using the pointer.
149 //
150 // Warning: as with any object, this call is only thread-safe if the WeakPtr
151 // instance isn't being re-assigned or reset() racily with this call.
Nicolas Ouellet-payeurff1eab62018-07-19 18:41:50152 bool MaybeValid() const;
[email protected]59326aac2009-09-25 23:34:34153
154 private:
[email protected]1edefc42011-08-26 17:32:29155 scoped_refptr<const Flag> flag_;
[email protected]3125d6462009-09-01 20:50:17156};
157
[email protected]0bea7252011-08-05 15:34:00158class BASE_EXPORT WeakReferenceOwner {
[email protected]3125d6462009-09-01 20:50:17159 public:
[email protected]3a3d47472010-07-15 21:03:54160 WeakReferenceOwner();
161 ~WeakReferenceOwner();
[email protected]59326aac2009-09-25 23:34:34162
[email protected]3a3d47472010-07-15 21:03:54163 WeakReference GetRef() const;
[email protected]3125d6462009-09-01 20:50:17164
Wezc5acb1ae2019-02-14 03:09:32165 bool HasRefs() const { return !flag_->HasOneRef(); }
[email protected]59326aac2009-09-25 23:34:34166
[email protected]3a3d47472010-07-15 21:03:54167 void Invalidate();
Scott Haseleyda865472023-05-10 19:03:11168 void BindToCurrentSequence();
[email protected]3125d6462009-09-01 20:50:17169
170 private:
Wez85ed9482019-11-13 02:23:31171 scoped_refptr<WeakReference::Flag> flag_;
[email protected]3125d6462009-09-01 20:50:17172};
173
[email protected]4c44b8442012-06-15 16:36:12174// This class provides a common implementation of common functions that would
175// otherwise get instantiated separately for each distinct instantiation of
176// SupportsWeakPtr<>.
177class SupportsWeakPtrBase {
178 public:
179 // A safe static downcast of a WeakPtr<Base> to WeakPtr<Derived>. This
180 // conversion will only compile if there is exists a Base which inherits
181 // from SupportsWeakPtr<Base>. See base::AsWeakPtr() below for a helper
182 // function that makes calling this easier.
François Degros75d898c2017-11-17 04:03:33183 //
184 // Precondition: t != nullptr
[email protected]4c44b8442012-06-15 16:36:12185 template<typename Derived>
186 static WeakPtr<Derived> StaticAsWeakPtr(Derived* t) {
tzik8df3dd02016-03-16 07:20:12187 static_assert(
188 std::is_base_of<internal::SupportsWeakPtrBase, Derived>::value,
189 "AsWeakPtr argument must inherit from SupportsWeakPtr");
François Degros75d898c2017-11-17 04:03:33190 return AsWeakPtrImpl<Derived>(t);
[email protected]4c44b8442012-06-15 16:36:12191 }
192
193 private:
194 // This template function uses type inference to find a Base of Derived
195 // which is an instance of SupportsWeakPtr<Base>. We can then safely
196 // static_cast the Base* to a Derived*.
197 template <typename Derived, typename Base>
François Degros75d898c2017-11-17 04:03:33198 static WeakPtr<Derived> AsWeakPtrImpl(SupportsWeakPtr<Base>* t) {
danakjcfcdfb7a2023-02-23 01:05:35199 WeakPtr<Base> weak = t->AsWeakPtr();
200 return WeakPtr<Derived>(weak.CloneWeakReference(),
201 static_cast<Derived*>(weak.ptr_));
[email protected]4c44b8442012-06-15 16:36:12202 }
203};
204
danakj45c91782021-09-29 18:23:57205// Forward declaration from safe_ptr.h.
206template <typename T>
danakjcfcdfb7a2023-02-23 01:05:35207SafeRef<T> MakeSafeRefFromWeakPtrInternals(internal::WeakReference&& ref,
danakj45c91782021-09-29 18:23:57208 T* ptr);
209
[email protected]3125d6462009-09-01 20:50:17210} // namespace internal
211
[email protected]3125d6462009-09-01 20:50:17212template <typename T> class WeakPtrFactory;
213
214// The WeakPtr class holds a weak reference to |T*|.
215//
216// This class is designed to be used like a normal pointer. You should always
217// null-test an object of this class before using it or invoking a method that
218// may result in the underlying object being destroyed.
219//
220// EXAMPLE:
221//
222// class Foo { ... };
223// WeakPtr<Foo> foo;
224// if (foo)
225// foo->method();
226//
227template <typename T>
danakjcfcdfb7a2023-02-23 01:05:35228class TRIVIAL_ABI WeakPtr {
[email protected]3125d6462009-09-01 20:50:17229 public:
Chris Watkins091d6292017-12-13 04:25:58230 WeakPtr() = default;
danakjcfcdfb7a2023-02-23 01:05:35231 // NOLINTNEXTLINE(google-explicit-constructor)
hanscc65b2992017-06-29 20:35:28232 WeakPtr(std::nullptr_t) {}
[email protected]3125d6462009-09-01 20:50:17233
[email protected]c33acdb2013-03-02 02:31:45234 // Allow conversion from U to T provided U "is a" T. Note that this
mek79016812016-06-24 21:29:04235 // is separate from the (implicit) copy and move constructors.
Alan Cutter6e972c82022-10-07 05:03:45236 template <typename U,
237 typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>
238 // NOLINTNEXTLINE(google-explicit-constructor)
danakjcfcdfb7a2023-02-23 01:05:35239 WeakPtr(const WeakPtr<U>& other) : ref_(other.ref_), ptr_(other.ptr_) {}
Alan Cutter6e972c82022-10-07 05:03:45240 template <typename U,
241 typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>
242 // NOLINTNEXTLINE(google-explicit-constructor)
danakjcfcdfb7a2023-02-23 01:05:35243 WeakPtr& operator=(const WeakPtr<U>& other) {
244 ref_ = other.ref_;
245 ptr_ = other.ptr_;
246 return *this;
hanscc65b2992017-06-29 20:35:28247 }
[email protected]3125d6462009-09-01 20:50:17248
danakjcfcdfb7a2023-02-23 01:05:35249 template <typename U,
250 typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>
251 // NOLINTNEXTLINE(google-explicit-constructor)
252 WeakPtr(WeakPtr<U>&& other)
253 : ref_(std::move(other.ref_)), ptr_(std::move(other.ptr_)) {}
254 template <typename U,
255 typename = std::enable_if_t<std::is_convertible_v<U*, T*>>>
256 // NOLINTNEXTLINE(google-explicit-constructor)
257 WeakPtr& operator=(WeakPtr<U>&& other) {
258 ref_ = std::move(other.ref_);
259 ptr_ = std::move(other.ptr_);
260 return *this;
hans526f714c2017-06-29 18:22:36261 }
[email protected]3125d6462009-09-01 20:50:17262
danakjcfcdfb7a2023-02-23 01:05:35263 T* get() const { return ref_.IsValid() ? ptr_ : nullptr; }
264
265 // Provide access to the underlying T as a reference. Will CHECK() if the T
266 // pointee is no longer alive.
[email protected]f1836f42012-02-29 06:59:03267 T& operator*() const {
Daniel Cheng0b308a02020-10-13 19:17:03268 CHECK(ref_.IsValid());
danakjcfcdfb7a2023-02-23 01:05:35269 return *ptr_;
[email protected]3125d6462009-09-01 20:50:17270 }
danakjcfcdfb7a2023-02-23 01:05:35271
272 // Used to call methods on the underlying T. Will CHECK() if the T pointee is
273 // no longer alive.
[email protected]3125d6462009-09-01 20:50:17274 T* operator->() const {
Daniel Cheng0b308a02020-10-13 19:17:03275 CHECK(ref_.IsValid());
danakjcfcdfb7a2023-02-23 01:05:35276 return ptr_;
[email protected]3125d6462009-09-01 20:50:17277 }
278
wezb9820d42016-06-22 23:41:04279 // Allow conditionals to test validity, e.g. if (weak_ptr) {...};
Wezcaf863b992018-05-01 11:03:29280 explicit operator bool() const { return get() != nullptr; }
[email protected]380b1392013-06-06 05:32:37281
danakjcfcdfb7a2023-02-23 01:05:35282 // Resets the WeakPtr to hold nothing.
283 //
284 // The `get()` method will return `nullptr` thereafter, and `MaybeValid()`
285 // will be `false`.
286 void reset() {
287 ref_.Reset();
288 ptr_ = nullptr;
289 }
290
Nicolas Ouellet-payeurff1eab62018-07-19 18:41:50291 // Returns false if the WeakPtr is confirmed to be invalid. This call is safe
292 // to make from any thread, e.g. to optimize away unnecessary work, but
danakjcfcdfb7a2023-02-23 01:05:35293 // RefIsValid() must always be called, on the correct sequence, before
Nicolas Ouellet-payeurff1eab62018-07-19 18:41:50294 // actually using the pointer.
295 //
296 // Warning: as with any object, this call is only thread-safe if the WeakPtr
297 // instance isn't being re-assigned or reset() racily with this call.
298 bool MaybeValid() const { return ref_.MaybeValid(); }
299
Trent Apted30f97fd2018-08-21 09:03:47300 // Returns whether the object |this| points to has been invalidated. This can
301 // be used to distinguish a WeakPtr to a destroyed object from one that has
Trent Apted453d0b5b2018-08-23 00:13:22302 // been explicitly set to null.
Trent Apted30f97fd2018-08-21 09:03:47303 bool WasInvalidated() const { return ptr_ && !ref_.IsValid(); }
304
[email protected]3125d6462009-09-01 20:50:17305 private:
[email protected]4c44b8442012-06-15 16:36:12306 friend class internal::SupportsWeakPtrBase;
[email protected]c33acdb2013-03-02 02:31:45307 template <typename U> friend class WeakPtr;
[email protected]3125d6462009-09-01 20:50:17308 friend class SupportsWeakPtr<T>;
309 friend class WeakPtrFactory<T>;
Alan Cutterc2d2c472022-10-20 02:14:43310 friend class WeakPtrFactory<std::remove_const_t<T>>;
[email protected]3125d6462009-09-01 20:50:17311
danakjcfcdfb7a2023-02-23 01:05:35312 WeakPtr(internal::WeakReference&& ref, T* ptr)
313 : ref_(std::move(ref)), ptr_(ptr) {
314 DCHECK(ptr);
315 }
316
317 internal::WeakReference CloneWeakReference() const { return ref_; }
318
319 internal::WeakReference ref_;
320
321 // This pointer is only valid when ref_.is_valid() is true. Otherwise, its
322 // value is undefined (as opposed to nullptr). The pointer is allowed to
323 // dangle as we verify its liveness through `ref_` before allowing access to
324 // the pointee. We don't use raw_ptr<T> here to prevent WeakPtr from keeping
325 // the memory allocation in quarantine, as it can't be accessed through the
326 // WeakPtr.
327 RAW_PTR_EXCLUSION T* ptr_ = nullptr;
[email protected]3125d6462009-09-01 20:50:17328};
329
wezb9820d42016-06-22 23:41:04330// Allow callers to compare WeakPtrs against nullptr to test validity.
331template <class T>
332bool operator!=(const WeakPtr<T>& weak_ptr, std::nullptr_t) {
333 return !(weak_ptr == nullptr);
334}
335template <class T>
336bool operator!=(std::nullptr_t, const WeakPtr<T>& weak_ptr) {
337 return weak_ptr != nullptr;
338}
339template <class T>
340bool operator==(const WeakPtr<T>& weak_ptr, std::nullptr_t) {
341 return weak_ptr.get() == nullptr;
342}
343template <class T>
344bool operator==(std::nullptr_t, const WeakPtr<T>& weak_ptr) {
345 return weak_ptr == nullptr;
346}
347
hansd2a722f2017-06-28 21:12:54348namespace internal {
349class BASE_EXPORT WeakPtrFactoryBase {
350 protected:
351 WeakPtrFactoryBase(uintptr_t ptr);
352 ~WeakPtrFactoryBase();
353 internal::WeakReferenceOwner weak_reference_owner_;
354 uintptr_t ptr_;
355};
356} // namespace internal
357
[email protected]2c691392013-04-25 20:47:18358// A class may be composed of a WeakPtrFactory and thereby
359// control how it exposes weak pointers to itself. This is helpful if you only
360// need weak pointers within the implementation of a class. This class is also
361// useful when working with primitive types. For example, you could have a
362// WeakPtrFactory<bool> that is used to pass around a weak reference to a bool.
363template <class T>
hansd2a722f2017-06-28 21:12:54364class WeakPtrFactory : public internal::WeakPtrFactoryBase {
[email protected]2c691392013-04-25 20:47:18365 public:
Peter Boström511258be2021-11-03 01:18:46366 WeakPtrFactory() = delete;
367
hansd2a722f2017-06-28 21:12:54368 explicit WeakPtrFactory(T* ptr)
369 : WeakPtrFactoryBase(reinterpret_cast<uintptr_t>(ptr)) {}
[email protected]2c691392013-04-25 20:47:18370
Peter Boström511258be2021-11-03 01:18:46371 WeakPtrFactory(const WeakPtrFactory&) = delete;
372 WeakPtrFactory& operator=(const WeakPtrFactory&) = delete;
373
Chris Watkins091d6292017-12-13 04:25:58374 ~WeakPtrFactory() = default;
[email protected]2c691392013-04-25 20:47:18375
Alan Cutterc2d2c472022-10-20 02:14:43376 WeakPtr<const T> GetWeakPtr() const {
377 return WeakPtr<const T>(weak_reference_owner_.GetRef(),
378 reinterpret_cast<const T*>(ptr_));
379 }
Alan Cutter4252ed22022-10-05 09:04:19380
Alan Cutterc2d2c472022-10-20 02:14:43381 template <int&... ExplicitArgumentBarrier,
382 typename U = T,
383 typename = std::enable_if_t<!std::is_const_v<U>>>
Alan Cutter4252ed22022-10-05 09:04:19384 WeakPtr<T> GetWeakPtr() {
385 return WeakPtr<T>(weak_reference_owner_.GetRef(),
386 reinterpret_cast<T*>(ptr_));
387 }
388
Alan Cutterc2d2c472022-10-20 02:14:43389 template <int&... ExplicitArgumentBarrier,
390 typename U = T,
391 typename = std::enable_if_t<!std::is_const_v<U>>>
Alan Cutter4252ed22022-10-05 09:04:19392 WeakPtr<T> GetMutableWeakPtr() const {
hansd2a722f2017-06-28 21:12:54393 return WeakPtr<T>(weak_reference_owner_.GetRef(),
394 reinterpret_cast<T*>(ptr_));
[email protected]2c691392013-04-25 20:47:18395 }
396
danakj45c91782021-09-29 18:23:57397 // Returns a smart pointer that is valid until the WeakPtrFactory is
398 // invalidated. Unlike WeakPtr, this smart pointer cannot be null, and cannot
399 // be checked to see if the WeakPtrFactory is invalidated. It's intended to
400 // express that the pointer will not (intentionally) outlive the `T` object it
401 // points to, and to crash safely in the case of a bug instead of causing a
402 // use-after-free. This type provides an alternative to WeakPtr to prevent
403 // use-after-free bugs without also introducing "fuzzy lifetimes" that can be
404 // checked for at runtime.
405 SafeRef<T> GetSafeRef() const {
406 return internal::MakeSafeRefFromWeakPtrInternals(
407 weak_reference_owner_.GetRef(), reinterpret_cast<T*>(ptr_));
408 }
409
[email protected]2c691392013-04-25 20:47:18410 // Call this method to invalidate all existing weak pointers.
411 void InvalidateWeakPtrs() {
412 DCHECK(ptr_);
413 weak_reference_owner_.Invalidate();
414 }
415
416 // Call this method to determine if any weak pointers exist.
417 bool HasWeakPtrs() const {
418 DCHECK(ptr_);
419 return weak_reference_owner_.HasRefs();
420 }
Scott Haseleyda865472023-05-10 19:03:11421
422 // Rebind the factory to the current sequence. This allows creating a task
423 // queue and associated weak pointers on a different thread from the one they
424 // are used on.
425 void BindToCurrentSequence(
426 PassKey<sequence_manager::internal::TaskQueueImpl>) {
427 weak_reference_owner_.BindToCurrentSequence();
428 }
[email protected]2c691392013-04-25 20:47:18429};
430
431// A class may extend from SupportsWeakPtr to let others take weak pointers to
432// it. This avoids the class itself implementing boilerplate to dispense weak
433// pointers. However, since SupportsWeakPtr's destructor won't invalidate
434// weak pointers to the class until after the derived class' members have been
435// destroyed, its use can lead to subtle use-after-destroy issues.
[email protected]3125d6462009-09-01 20:50:17436template <class T>
[email protected]4c44b8442012-06-15 16:36:12437class SupportsWeakPtr : public internal::SupportsWeakPtrBase {
[email protected]3125d6462009-09-01 20:50:17438 public:
Chris Watkins091d6292017-12-13 04:25:58439 SupportsWeakPtr() = default;
[email protected]3125d6462009-09-01 20:50:17440
Peter Boström75cd3c02021-09-28 15:23:18441 SupportsWeakPtr(const SupportsWeakPtr&) = delete;
442 SupportsWeakPtr& operator=(const SupportsWeakPtr&) = delete;
443
[email protected]3125d6462009-09-01 20:50:17444 WeakPtr<T> AsWeakPtr() {
445 return WeakPtr<T>(weak_reference_owner_.GetRef(), static_cast<T*>(this));
446 }
447
[email protected]cb932482012-06-26 06:23:00448 protected:
Chris Watkins091d6292017-12-13 04:25:58449 ~SupportsWeakPtr() = default;
[email protected]cb932482012-06-26 06:23:00450
[email protected]3125d6462009-09-01 20:50:17451 private:
452 internal::WeakReferenceOwner weak_reference_owner_;
[email protected]3125d6462009-09-01 20:50:17453};
454
[email protected]4c44b8442012-06-15 16:36:12455// Helper function that uses type deduction to safely return a WeakPtr<Derived>
456// when Derived doesn't directly extend SupportsWeakPtr<Derived>, instead it
457// extends a Base that extends SupportsWeakPtr<Base>.
458//
459// EXAMPLE:
460// class Base : public base::SupportsWeakPtr<Producer> {};
461// class Derived : public Base {};
462//
463// Derived derived;
464// base::WeakPtr<Derived> ptr = base::AsWeakPtr(&derived);
465//
466// Note that the following doesn't work (invalid type conversion) since
467// Derived::AsWeakPtr() is WeakPtr<Base> SupportsWeakPtr<Base>::AsWeakPtr(),
468// and there's no way to safely cast WeakPtr<Base> to WeakPtr<Derived> at
469// the caller.
470//
471// base::WeakPtr<Derived> ptr = derived.AsWeakPtr(); // Fails.
472
473template <typename Derived>
474WeakPtr<Derived> AsWeakPtr(Derived* t) {
475 return internal::SupportsWeakPtrBase::StaticAsWeakPtr<Derived>(t);
476}
477
[email protected]3125d6462009-09-01 20:50:17478} // namespace base
479
[email protected]3b63f8f42011-03-28 01:54:15480#endif // BASE_MEMORY_WEAK_PTR_H_