blob: 032f5973138c5f02ec458d203caedeb92e37e955 [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"
Paul Semel5eac04a12023-06-07 18:17:3284#include "base/memory/safe_ref_traits.h"
[email protected]d52426c2013-07-30 19:26:4085#include "base/sequence_checker.h"
Nicolas Ouellet-payeurff1eab62018-07-19 18:41:5086#include "base/synchronization/atomic_flag.h"
Joe Mason0f6f6112024-02-08 17:48:1087
[email protected]3125d6462009-09-01 20:50:1788namespace base {
89
Scott Haseleyda865472023-05-10 19:03:1190namespace sequence_manager::internal {
91class TaskQueueImpl;
92}
93
Peter Kasting134ef9af2024-12-28 02:30:0994template <typename T>
95class WeakPtr;
[email protected]4c44b8442012-06-15 16:36:1296
[email protected]3125d6462009-09-01 20:50:1797namespace internal {
98// These classes are part of the WeakPtr implementation.
99// DO NOT USE THESE CLASSES DIRECTLY YOURSELF.
100
Lukasz Anforowicz7623e192021-12-02 23:19:36101class BASE_EXPORT TRIVIAL_ABI WeakReference {
[email protected]3125d6462009-09-01 20:50:17102 public:
Wezfb4a5282018-05-01 09:02:11103 // Although Flag is bound to a specific SequencedTaskRunner, it may be
104 // deleted from another via base::WeakPtr::~WeakPtr().
[email protected]a827a562014-06-11 00:37:42105 class BASE_EXPORT Flag : public RefCountedThreadSafe<Flag> {
[email protected]d52e9702009-09-17 00:31:09106 public:
[email protected]1edefc42011-08-26 17:32:29107 Flag();
[email protected]59326aac2009-09-25 23:34:34108
hans24046fd2017-06-29 22:07:42109 void Invalidate();
Hans Wennborg4cfa3012017-08-08 03:33:38110 bool IsValid() const;
[email protected]59326aac2009-09-25 23:34:34111
Nicolas Ouellet-payeurff1eab62018-07-19 18:41:50112 bool MaybeValid() const;
113
Igor Bukanov933bad992021-09-10 19:47:25114#if DCHECK_IS_ON()
Wezc5acb1ae2019-02-14 03:09:32115 void DetachFromSequence();
Scott Haseleyda865472023-05-10 19:03:11116 void BindToCurrentSequence();
Igor Bukanov933bad992021-09-10 19:47:25117#endif
Wezc5acb1ae2019-02-14 03:09:32118
[email protected]59326aac2009-09-25 23:34:34119 private:
[email protected]05b1cd612011-04-11 20:47:25120 friend class base::RefCountedThreadSafe<Flag>;
121
122 ~Flag();
123
Nicolas Ouellet-payeurff1eab62018-07-19 18:41:50124 SEQUENCE_CHECKER(sequence_checker_);
125 AtomicFlag invalidated_;
[email protected]3125d6462009-09-01 20:50:17126 };
127
[email protected]3a3d47472010-07-15 21:03:54128 WeakReference();
Wez7eedd9e2018-01-23 00:27:05129 explicit WeakReference(const scoped_refptr<Flag>& flag);
[email protected]201366472010-07-16 17:22:49130 ~WeakReference();
[email protected]59326aac2009-09-25 23:34:34131
mek79016812016-06-24 21:29:04132 WeakReference(const WeakReference& other);
danakjcfcdfb7a2023-02-23 01:05:35133 WeakReference& operator=(const WeakReference& other);
mek79016812016-06-24 21:29:04134
danakjcfcdfb7a2023-02-23 01:05:35135 WeakReference(WeakReference&& other) noexcept;
136 WeakReference& operator=(WeakReference&& other) noexcept;
137
138 void Reset();
139 // Returns whether the WeakReference is valid, meaning the WeakPtrFactory has
140 // not invalidated the pointer. Unlike, RefIsMaybeValid(), this may only be
141 // called from the same sequence as where the WeakPtr was created.
Nicolas Ouellet-payeurff1eab62018-07-19 18:41:50142 bool IsValid() const;
danakjcfcdfb7a2023-02-23 01:05:35143 // Returns false if the WeakReference is confirmed to be invalid. This call is
144 // safe to make from any thread, e.g. to optimize away unnecessary work, but
145 // RefIsValid() must always be called, on the correct sequence, before
146 // actually using the pointer.
147 //
148 // Warning: as with any object, this call is only thread-safe if the WeakPtr
149 // instance isn't being re-assigned or reset() racily with this call.
Nicolas Ouellet-payeurff1eab62018-07-19 18:41:50150 bool MaybeValid() const;
[email protected]59326aac2009-09-25 23:34:34151
152 private:
[email protected]1edefc42011-08-26 17:32:29153 scoped_refptr<const Flag> flag_;
[email protected]3125d6462009-09-01 20:50:17154};
155
[email protected]0bea7252011-08-05 15:34:00156class BASE_EXPORT WeakReferenceOwner {
[email protected]3125d6462009-09-01 20:50:17157 public:
[email protected]3a3d47472010-07-15 21:03:54158 WeakReferenceOwner();
159 ~WeakReferenceOwner();
[email protected]59326aac2009-09-25 23:34:34160
[email protected]3a3d47472010-07-15 21:03:54161 WeakReference GetRef() const;
[email protected]3125d6462009-09-01 20:50:17162
Wezc5acb1ae2019-02-14 03:09:32163 bool HasRefs() const { return !flag_->HasOneRef(); }
[email protected]59326aac2009-09-25 23:34:34164
[email protected]3a3d47472010-07-15 21:03:54165 void Invalidate();
François Dorayd1a2bfde2025-06-20 00:39:30166 void InvalidateAndDoom();
Scott Haseleyda865472023-05-10 19:03:11167 void BindToCurrentSequence();
[email protected]3125d6462009-09-01 20:50:17168
169 private:
Wez85ed9482019-11-13 02:23:31170 scoped_refptr<WeakReference::Flag> flag_;
[email protected]3125d6462009-09-01 20:50:17171};
172
danakj45c91782021-09-29 18:23:57173// Forward declaration from safe_ptr.h.
174template <typename T>
danakjcfcdfb7a2023-02-23 01:05:35175SafeRef<T> MakeSafeRefFromWeakPtrInternals(internal::WeakReference&& ref,
danakj45c91782021-09-29 18:23:57176 T* ptr);
177
[email protected]3125d6462009-09-01 20:50:17178} // namespace internal
179
Peter Kasting134ef9af2024-12-28 02:30:09180template <typename T>
181class WeakPtrFactory;
[email protected]3125d6462009-09-01 20:50:17182
183// The WeakPtr class holds a weak reference to |T*|.
184//
185// This class is designed to be used like a normal pointer. You should always
186// null-test an object of this class before using it or invoking a method that
187// may result in the underlying object being destroyed.
188//
189// EXAMPLE:
190//
191// class Foo { ... };
192// WeakPtr<Foo> foo;
193// if (foo)
194// foo->method();
195//
Joe Mason192000b2025-03-18 22:04:57196// WeakPtr intentionally doesn't implement operator== or operator<=>, because
197// comparisons of weak references are inherently unstable. If the comparison
198// takes validity into account, the result can change at any time as pointers
199// are invalidated. If it depends only on the underlying pointer value, even
200// after the pointer is invalidated, unrelated WeakPtrs can unexpectedly
201// compare equal if the address is reused.
[email protected]3125d6462009-09-01 20:50:17202template <typename T>
danakjcfcdfb7a2023-02-23 01:05:35203class TRIVIAL_ABI WeakPtr {
[email protected]3125d6462009-09-01 20:50:17204 public:
Chris Watkins091d6292017-12-13 04:25:58205 WeakPtr() = default;
danakjcfcdfb7a2023-02-23 01:05:35206 // NOLINTNEXTLINE(google-explicit-constructor)
hanscc65b2992017-06-29 20:35:28207 WeakPtr(std::nullptr_t) {}
[email protected]3125d6462009-09-01 20:50:17208
[email protected]c33acdb2013-03-02 02:31:45209 // Allow conversion from U to T provided U "is a" T. Note that this
mek79016812016-06-24 21:29:04210 // is separate from the (implicit) copy and move constructors.
Daniel Cheng8d4b30d2023-11-14 20:25:54211 template <typename U>
212 requires(std::convertible_to<U*, T*>)
Alan Cutter6e972c82022-10-07 05:03:45213 // NOLINTNEXTLINE(google-explicit-constructor)
danakjcfcdfb7a2023-02-23 01:05:35214 WeakPtr(const WeakPtr<U>& other) : ref_(other.ref_), ptr_(other.ptr_) {}
Daniel Cheng8d4b30d2023-11-14 20:25:54215 template <typename U>
216 requires(std::convertible_to<U*, T*>)
Alan Cutter6e972c82022-10-07 05:03:45217 // NOLINTNEXTLINE(google-explicit-constructor)
danakjcfcdfb7a2023-02-23 01:05:35218 WeakPtr& operator=(const WeakPtr<U>& other) {
219 ref_ = other.ref_;
220 ptr_ = other.ptr_;
221 return *this;
hanscc65b2992017-06-29 20:35:28222 }
[email protected]3125d6462009-09-01 20:50:17223
Daniel Cheng8d4b30d2023-11-14 20:25:54224 template <typename U>
225 requires(std::convertible_to<U*, T*>)
danakjcfcdfb7a2023-02-23 01:05:35226 // NOLINTNEXTLINE(google-explicit-constructor)
227 WeakPtr(WeakPtr<U>&& other)
228 : ref_(std::move(other.ref_)), ptr_(std::move(other.ptr_)) {}
Daniel Cheng8d4b30d2023-11-14 20:25:54229 template <typename U>
230 requires(std::convertible_to<U*, T*>)
danakjcfcdfb7a2023-02-23 01:05:35231 // NOLINTNEXTLINE(google-explicit-constructor)
232 WeakPtr& operator=(WeakPtr<U>&& other) {
233 ref_ = std::move(other.ref_);
234 ptr_ = std::move(other.ptr_);
235 return *this;
hans526f714c2017-06-29 18:22:36236 }
[email protected]3125d6462009-09-01 20:50:17237
danakjcfcdfb7a2023-02-23 01:05:35238 T* get() const { return ref_.IsValid() ? ptr_ : nullptr; }
239
240 // Provide access to the underlying T as a reference. Will CHECK() if the T
241 // pointee is no longer alive.
[email protected]f1836f42012-02-29 06:59:03242 T& operator*() const {
Daniel Cheng0b308a02020-10-13 19:17:03243 CHECK(ref_.IsValid());
danakjcfcdfb7a2023-02-23 01:05:35244 return *ptr_;
[email protected]3125d6462009-09-01 20:50:17245 }
danakjcfcdfb7a2023-02-23 01:05:35246
247 // Used to call methods on the underlying T. Will CHECK() if the T pointee is
248 // no longer alive.
[email protected]3125d6462009-09-01 20:50:17249 T* operator->() const {
Daniel Cheng0b308a02020-10-13 19:17:03250 CHECK(ref_.IsValid());
danakjcfcdfb7a2023-02-23 01:05:35251 return ptr_;
[email protected]3125d6462009-09-01 20:50:17252 }
253
wezb9820d42016-06-22 23:41:04254 // Allow conditionals to test validity, e.g. if (weak_ptr) {...};
Wezcaf863b992018-05-01 11:03:29255 explicit operator bool() const { return get() != nullptr; }
[email protected]380b1392013-06-06 05:32:37256
danakjcfcdfb7a2023-02-23 01:05:35257 // Resets the WeakPtr to hold nothing.
258 //
259 // The `get()` method will return `nullptr` thereafter, and `MaybeValid()`
260 // will be `false`.
261 void reset() {
262 ref_.Reset();
263 ptr_ = nullptr;
264 }
265
Erik Chen7c001192024-02-07 23:38:46266 // Do not use this method. Almost all callers should instead use operator
267 // bool().
268 //
269 // There are a few rare cases where the caller intentionally needs to check
270 // validity of a base::WeakPtr on a sequence different from the bound sequence
271 // as an unavoidable performance optimization. This is the only valid use-case
272 // for this method. See
273 // https://docs.google.com/document/d/1IGzq9Nx69GS_2iynGmPWo5sFAD2DcCyBY1zIvZwF7k8
274 // for details.
275 //
Nicolas Ouellet-payeurff1eab62018-07-19 18:41:50276 // Returns false if the WeakPtr is confirmed to be invalid. This call is safe
277 // to make from any thread, e.g. to optimize away unnecessary work, but
danakjcfcdfb7a2023-02-23 01:05:35278 // RefIsValid() must always be called, on the correct sequence, before
Nicolas Ouellet-payeurff1eab62018-07-19 18:41:50279 // actually using the pointer.
280 //
281 // Warning: as with any object, this call is only thread-safe if the WeakPtr
282 // instance isn't being re-assigned or reset() racily with this call.
283 bool MaybeValid() const { return ref_.MaybeValid(); }
284
Trent Apted30f97fd2018-08-21 09:03:47285 // Returns whether the object |this| points to has been invalidated. This can
286 // be used to distinguish a WeakPtr to a destroyed object from one that has
Trent Apted453d0b5b2018-08-23 00:13:22287 // been explicitly set to null.
Trent Apted30f97fd2018-08-21 09:03:47288 bool WasInvalidated() const { return ptr_ && !ref_.IsValid(); }
289
[email protected]3125d6462009-09-01 20:50:17290 private:
Peter Kasting134ef9af2024-12-28 02:30:09291 template <typename U>
292 friend class WeakPtr;
[email protected]3125d6462009-09-01 20:50:17293 friend class WeakPtrFactory<T>;
Alan Cutterc2d2c472022-10-20 02:14:43294 friend class WeakPtrFactory<std::remove_const_t<T>>;
[email protected]3125d6462009-09-01 20:50:17295
danakjcfcdfb7a2023-02-23 01:05:35296 WeakPtr(internal::WeakReference&& ref, T* ptr)
297 : ref_(std::move(ref)), ptr_(ptr) {
298 DCHECK(ptr);
299 }
300
301 internal::WeakReference CloneWeakReference() const { return ref_; }
302
303 internal::WeakReference ref_;
304
305 // This pointer is only valid when ref_.is_valid() is true. Otherwise, its
306 // value is undefined (as opposed to nullptr). The pointer is allowed to
307 // dangle as we verify its liveness through `ref_` before allowing access to
308 // the pointee. We don't use raw_ptr<T> here to prevent WeakPtr from keeping
309 // the memory allocation in quarantine, as it can't be accessed through the
310 // WeakPtr.
311 RAW_PTR_EXCLUSION T* ptr_ = nullptr;
[email protected]3125d6462009-09-01 20:50:17312};
313
wezb9820d42016-06-22 23:41:04314// Allow callers to compare WeakPtrs against nullptr to test validity.
315template <class T>
316bool operator!=(const WeakPtr<T>& weak_ptr, std::nullptr_t) {
317 return !(weak_ptr == nullptr);
318}
319template <class T>
320bool operator!=(std::nullptr_t, const WeakPtr<T>& weak_ptr) {
321 return weak_ptr != nullptr;
322}
323template <class T>
324bool operator==(const WeakPtr<T>& weak_ptr, std::nullptr_t) {
325 return weak_ptr.get() == nullptr;
326}
327template <class T>
328bool operator==(std::nullptr_t, const WeakPtr<T>& weak_ptr) {
329 return weak_ptr == nullptr;
330}
331
hansd2a722f2017-06-28 21:12:54332namespace internal {
333class BASE_EXPORT WeakPtrFactoryBase {
334 protected:
335 WeakPtrFactoryBase(uintptr_t ptr);
336 ~WeakPtrFactoryBase();
337 internal::WeakReferenceOwner weak_reference_owner_;
338 uintptr_t ptr_;
339};
340} // namespace internal
341
Joe Mason0f6f6112024-02-08 17:48:10342namespace subtle {
343
344// Restricts access to WeakPtrFactory::BindToCurrentSequence() to authorized
345// callers.
346class BASE_EXPORT BindWeakPtrFactoryPassKey {
347 private:
Sorin Jianu1ed1f6c2024-09-28 00:31:40348 BindWeakPtrFactoryPassKey() = default;
Joe Mason0f6f6112024-02-08 17:48:10349
350 friend class BindWeakPtrFactoryForTesting;
Joe Mason0f6f6112024-02-08 17:48:10351 friend class sequence_manager::internal::TaskQueueImpl;
352};
353
354} // namespace subtle
355
[email protected]2c691392013-04-25 20:47:18356// A class may be composed of a WeakPtrFactory and thereby
357// control how it exposes weak pointers to itself. This is helpful if you only
358// need weak pointers within the implementation of a class. This class is also
359// useful when working with primitive types. For example, you could have a
360// WeakPtrFactory<bool> that is used to pass around a weak reference to a bool.
361template <class T>
hansd2a722f2017-06-28 21:12:54362class WeakPtrFactory : public internal::WeakPtrFactoryBase {
[email protected]2c691392013-04-25 20:47:18363 public:
Peter Boström511258be2021-11-03 01:18:46364 WeakPtrFactory() = delete;
365
hansd2a722f2017-06-28 21:12:54366 explicit WeakPtrFactory(T* ptr)
367 : WeakPtrFactoryBase(reinterpret_cast<uintptr_t>(ptr)) {}
[email protected]2c691392013-04-25 20:47:18368
Peter Boström511258be2021-11-03 01:18:46369 WeakPtrFactory(const WeakPtrFactory&) = delete;
370 WeakPtrFactory& operator=(const WeakPtrFactory&) = delete;
371
Chris Watkins091d6292017-12-13 04:25:58372 ~WeakPtrFactory() = default;
[email protected]2c691392013-04-25 20:47:18373
Alan Cutterc2d2c472022-10-20 02:14:43374 WeakPtr<const T> GetWeakPtr() const {
375 return WeakPtr<const T>(weak_reference_owner_.GetRef(),
376 reinterpret_cast<const T*>(ptr_));
377 }
Alan Cutter4252ed22022-10-05 09:04:19378
Daniel Cheng8d4b30d2023-11-14 20:25:54379 WeakPtr<T> GetWeakPtr()
380 requires(!std::is_const_v<T>)
381 {
Alan Cutter4252ed22022-10-05 09:04:19382 return WeakPtr<T>(weak_reference_owner_.GetRef(),
383 reinterpret_cast<T*>(ptr_));
384 }
385
Daniel Cheng8d4b30d2023-11-14 20:25:54386 WeakPtr<T> GetMutableWeakPtr() const
387 requires(!std::is_const_v<T>)
388 {
hansd2a722f2017-06-28 21:12:54389 return WeakPtr<T>(weak_reference_owner_.GetRef(),
390 reinterpret_cast<T*>(ptr_));
[email protected]2c691392013-04-25 20:47:18391 }
392
danakj45c91782021-09-29 18:23:57393 // Returns a smart pointer that is valid until the WeakPtrFactory is
394 // invalidated. Unlike WeakPtr, this smart pointer cannot be null, and cannot
395 // be checked to see if the WeakPtrFactory is invalidated. It's intended to
396 // express that the pointer will not (intentionally) outlive the `T` object it
397 // points to, and to crash safely in the case of a bug instead of causing a
398 // use-after-free. This type provides an alternative to WeakPtr to prevent
399 // use-after-free bugs without also introducing "fuzzy lifetimes" that can be
400 // checked for at runtime.
401 SafeRef<T> GetSafeRef() const {
402 return internal::MakeSafeRefFromWeakPtrInternals(
403 weak_reference_owner_.GetRef(), reinterpret_cast<T*>(ptr_));
404 }
405
François Dorayd1a2bfde2025-06-20 00:39:30406 // Invalidates all existing weak pointers.
[email protected]2c691392013-04-25 20:47:18407 void InvalidateWeakPtrs() {
408 DCHECK(ptr_);
409 weak_reference_owner_.Invalidate();
410 }
411
François Dorayd1a2bfde2025-06-20 00:39:30412 // Invalidates all existing weak pointers, and makes the factory unusable
413 // (cannot call GetWeakPtr after this). This is more efficient than
414 // InvalidateWeakPtrs().
415 void InvalidateWeakPtrsAndDoom() {
[email protected]2c691392013-04-25 20:47:18416 DCHECK(ptr_);
François Dorayd1a2bfde2025-06-20 00:39:30417 weak_reference_owner_.InvalidateAndDoom();
418 ptr_ = 0;
[email protected]2c691392013-04-25 20:47:18419 }
Scott Haseleyda865472023-05-10 19:03:11420
François Dorayd1a2bfde2025-06-20 00:39:30421 // Call this method to determine if any weak pointers exist.
422 bool HasWeakPtrs() const { return ptr_ && weak_reference_owner_.HasRefs(); }
423
Joe Mason0f6f6112024-02-08 17:48:10424 // Rebind the factory to the current sequence. This allows creating an object
425 // and associated weak pointers on a different thread from the one they are
426 // used on.
427 void BindToCurrentSequence(subtle::BindWeakPtrFactoryPassKey) {
Scott Haseleyda865472023-05-10 19:03:11428 weak_reference_owner_.BindToCurrentSequence();
429 }
[email protected]2c691392013-04-25 20:47:18430};
431
[email protected]3125d6462009-09-01 20:50:17432} // namespace base
433
[email protected]3b63f8f42011-03-28 01:54:15434#endif // BASE_MEMORY_WEAK_PTR_H_