1 // Copyright 2012 The Chromium Authors 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 // void SpawnWorker() { Worker::StartNew(weak_factory_.GetWeakPtr()); } 20 // void WorkComplete(const Result& result) { ... } 21 // private: 22 // // 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. 25 // WeakPtrFactory<Controller> weak_factory_{this}; 26 // }; 27 // 28 // class Worker { 29 // public: 30 // static void StartNew(WeakPtr<Controller> controller) { 31 // // Move WeakPtr when possible to avoid atomic refcounting churn on its 32 // // internal state. 33 // Worker* worker = new Worker(std::move(controller)); 34 // // Kick off asynchronous processing... 35 // } 36 // private: 37 // Worker(WeakPtr<Controller> controller) 38 // : controller_(std::move(controller)) {} 39 // void DidCompleteAsynchronousProcessing(const Result& result) { 40 // if (controller_) 41 // controller_->WorkComplete(result); 42 // } 43 // WeakPtr<Controller> controller_; 44 // }; 45 // 46 // 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 52 // Weak pointers may be passed safely between sequences, but must always be 53 // dereferenced and invalidated on the same SequencedTaskRunner otherwise 54 // checking the pointer would be racey. 55 // 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 58 // sequence or current SequencedWorkerPool token, and cannot be dereferenced or 59 // 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. 62 // 63 // 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 68 // the correct sequence to enforce that other WeakPtr objects will enforce they 69 // are used on the desired sequence. 70 71 #ifndef BASE_MEMORY_WEAK_PTR_H_ 72 #define BASE_MEMORY_WEAK_PTR_H_ 73 74 #include <cstddef> 75 #include <type_traits> 76 #include <utility> 77 78 #include "base/base_export.h" 79 #include "base/check.h" 80 #include "base/compiler_specific.h" 81 #include "base/dcheck_is_on.h" 82 #include "base/memory/raw_ptr.h" 83 #include "base/memory/ref_counted.h" 84 #include "base/memory/safe_ref_traits.h" 85 #include "base/sequence_checker.h" 86 #include "base/synchronization/atomic_flag.h" 87 #include "base/types/pass_key.h" 88 89 namespace base { 90 91 namespace sequence_manager::internal { 92 class TaskQueueImpl; 93 } 94 95 template <typename T> class SupportsWeakPtr; 96 template <typename T> class WeakPtr; 97 98 namespace internal { 99 // These classes are part of the WeakPtr implementation. 100 // DO NOT USE THESE CLASSES DIRECTLY YOURSELF. 101 102 class BASE_EXPORT TRIVIAL_ABI WeakReference { 103 public: 104 // Although Flag is bound to a specific SequencedTaskRunner, it may be 105 // deleted from another via base::WeakPtr::~WeakPtr(). 106 class BASE_EXPORT Flag : public RefCountedThreadSafe<Flag> { 107 public: 108 Flag(); 109 110 void Invalidate(); 111 bool IsValid() const; 112 113 bool MaybeValid() const; 114 115 #if DCHECK_IS_ON() 116 void DetachFromSequence(); 117 void BindToCurrentSequence(); 118 #endif 119 120 private: 121 friend class base::RefCountedThreadSafe<Flag>; 122 123 ~Flag(); 124 125 SEQUENCE_CHECKER(sequence_checker_); 126 AtomicFlag invalidated_; 127 }; 128 129 WeakReference(); 130 explicit WeakReference(const scoped_refptr<Flag>& flag); 131 ~WeakReference(); 132 133 WeakReference(const WeakReference& other); 134 WeakReference& operator=(const WeakReference& other); 135 136 WeakReference(WeakReference&& other) noexcept; 137 WeakReference& operator=(WeakReference&& other) noexcept; 138 139 void Reset(); 140 // Returns whether the WeakReference is valid, meaning the WeakPtrFactory has 141 // not invalidated the pointer. Unlike, RefIsMaybeValid(), this may only be 142 // called from the same sequence as where the WeakPtr was created. 143 bool IsValid() const; 144 // Returns false if the WeakReference is confirmed to be invalid. This call is 145 // safe to make from any thread, e.g. to optimize away unnecessary work, but 146 // RefIsValid() must always be called, on the correct sequence, before 147 // actually using the pointer. 148 // 149 // Warning: as with any object, this call is only thread-safe if the WeakPtr 150 // instance isn't being re-assigned or reset() racily with this call. 151 bool MaybeValid() const; 152 153 private: 154 scoped_refptr<const Flag> flag_; 155 }; 156 157 class BASE_EXPORT WeakReferenceOwner { 158 public: 159 WeakReferenceOwner(); 160 ~WeakReferenceOwner(); 161 162 WeakReference GetRef() const; 163 HasRefs()164 bool HasRefs() const { return !flag_->HasOneRef(); } 165 166 void Invalidate(); 167 void BindToCurrentSequence(); 168 169 private: 170 scoped_refptr<WeakReference::Flag> flag_; 171 }; 172 173 // This class provides a common implementation of common functions that would 174 // otherwise get instantiated separately for each distinct instantiation of 175 // SupportsWeakPtr<>. 176 class SupportsWeakPtrBase { 177 public: 178 // A safe static downcast of a WeakPtr<Base> to WeakPtr<Derived>. This 179 // conversion will only compile if Derived singly inherits from 180 // SupportsWeakPtr<Base>. See base::AsWeakPtr() below for a helper function 181 // that makes calling this easier. 182 // 183 // Precondition: t != nullptr 184 template<typename Derived> StaticAsWeakPtr(Derived * t)185 static WeakPtr<Derived> StaticAsWeakPtr(Derived* t) { 186 static_assert(std::is_base_of_v<internal::SupportsWeakPtrBase, Derived>, 187 "AsWeakPtr argument must inherit from SupportsWeakPtr"); 188 using Base = typename decltype(ExtractSinglyInheritedBase(t))::Base; 189 // Ensure SupportsWeakPtr<Base>::AsWeakPtr() is called even if the subclass 190 // hides or overloads it. 191 WeakPtr<Base> weak = static_cast<SupportsWeakPtr<Base>*>(t)->AsWeakPtr(); 192 return WeakPtr<Derived>(weak.CloneWeakReference(), 193 static_cast<Derived*>(weak.ptr_)); 194 } 195 196 private: 197 // This class can only be instantiated if the constructor argument inherits 198 // from SupportsWeakPtr<T> in exactly one way. 199 template <typename T> 200 struct ExtractSinglyInheritedBase; 201 template <typename T> 202 struct ExtractSinglyInheritedBase<SupportsWeakPtr<T>> { 203 using Base = T; 204 explicit ExtractSinglyInheritedBase(SupportsWeakPtr<T>*); 205 }; 206 template <typename T> 207 ExtractSinglyInheritedBase(SupportsWeakPtr<T>*) 208 -> ExtractSinglyInheritedBase<SupportsWeakPtr<T>>; 209 }; 210 211 // Forward declaration from safe_ptr.h. 212 template <typename T> 213 SafeRef<T> MakeSafeRefFromWeakPtrInternals(internal::WeakReference&& ref, 214 T* ptr); 215 216 } // namespace internal 217 218 template <typename T> class WeakPtrFactory; 219 220 // The WeakPtr class holds a weak reference to |T*|. 221 // 222 // This class is designed to be used like a normal pointer. You should always 223 // null-test an object of this class before using it or invoking a method that 224 // may result in the underlying object being destroyed. 225 // 226 // EXAMPLE: 227 // 228 // class Foo { ... }; 229 // WeakPtr<Foo> foo; 230 // if (foo) 231 // foo->method(); 232 // 233 template <typename T> 234 class TRIVIAL_ABI WeakPtr { 235 public: 236 WeakPtr() = default; 237 // NOLINTNEXTLINE(google-explicit-constructor) 238 WeakPtr(std::nullptr_t) {} 239 240 // Allow conversion from U to T provided U "is a" T. Note that this 241 // is separate from the (implicit) copy and move constructors. 242 template <typename U> 243 requires(std::convertible_to<U*, T*>) 244 // NOLINTNEXTLINE(google-explicit-constructor) 245 WeakPtr(const WeakPtr<U>& other) : ref_(other.ref_), ptr_(other.ptr_) {} 246 template <typename U> 247 requires(std::convertible_to<U*, T*>) 248 // NOLINTNEXTLINE(google-explicit-constructor) 249 WeakPtr& operator=(const WeakPtr<U>& other) { 250 ref_ = other.ref_; 251 ptr_ = other.ptr_; 252 return *this; 253 } 254 255 template <typename U> 256 requires(std::convertible_to<U*, T*>) 257 // NOLINTNEXTLINE(google-explicit-constructor) 258 WeakPtr(WeakPtr<U>&& other) 259 : ref_(std::move(other.ref_)), ptr_(std::move(other.ptr_)) {} 260 template <typename U> 261 requires(std::convertible_to<U*, T*>) 262 // NOLINTNEXTLINE(google-explicit-constructor) 263 WeakPtr& operator=(WeakPtr<U>&& other) { 264 ref_ = std::move(other.ref_); 265 ptr_ = std::move(other.ptr_); 266 return *this; 267 } 268 269 T* get() const { return ref_.IsValid() ? ptr_ : nullptr; } 270 271 // Provide access to the underlying T as a reference. Will CHECK() if the T 272 // pointee is no longer alive. 273 T& operator*() const { 274 CHECK(ref_.IsValid()); 275 return *ptr_; 276 } 277 278 // Used to call methods on the underlying T. Will CHECK() if the T pointee is 279 // no longer alive. 280 T* operator->() const { 281 CHECK(ref_.IsValid()); 282 return ptr_; 283 } 284 285 // Allow conditionals to test validity, e.g. if (weak_ptr) {...}; 286 explicit operator bool() const { return get() != nullptr; } 287 288 // Resets the WeakPtr to hold nothing. 289 // 290 // The `get()` method will return `nullptr` thereafter, and `MaybeValid()` 291 // will be `false`. 292 void reset() { 293 ref_.Reset(); 294 ptr_ = nullptr; 295 } 296 297 // Returns false if the WeakPtr is confirmed to be invalid. This call is safe 298 // to make from any thread, e.g. to optimize away unnecessary work, but 299 // RefIsValid() must always be called, on the correct sequence, before 300 // actually using the pointer. 301 // 302 // Warning: as with any object, this call is only thread-safe if the WeakPtr 303 // instance isn't being re-assigned or reset() racily with this call. 304 bool MaybeValid() const { return ref_.MaybeValid(); } 305 306 // Returns whether the object |this| points to has been invalidated. This can 307 // be used to distinguish a WeakPtr to a destroyed object from one that has 308 // been explicitly set to null. 309 bool WasInvalidated() const { return ptr_ && !ref_.IsValid(); } 310 311 private: 312 friend class internal::SupportsWeakPtrBase; 313 template <typename U> friend class WeakPtr; 314 friend class SupportsWeakPtr<T>; 315 friend class WeakPtrFactory<T>; 316 friend class WeakPtrFactory<std::remove_const_t<T>>; 317 318 WeakPtr(internal::WeakReference&& ref, T* ptr) 319 : ref_(std::move(ref)), ptr_(ptr) { 320 DCHECK(ptr); 321 } 322 323 internal::WeakReference CloneWeakReference() const { return ref_; } 324 325 internal::WeakReference ref_; 326 327 // This pointer is only valid when ref_.is_valid() is true. Otherwise, its 328 // value is undefined (as opposed to nullptr). The pointer is allowed to 329 // dangle as we verify its liveness through `ref_` before allowing access to 330 // the pointee. We don't use raw_ptr<T> here to prevent WeakPtr from keeping 331 // the memory allocation in quarantine, as it can't be accessed through the 332 // WeakPtr. 333 RAW_PTR_EXCLUSION T* ptr_ = nullptr; 334 }; 335 336 // Allow callers to compare WeakPtrs against nullptr to test validity. 337 template <class T> 338 bool operator!=(const WeakPtr<T>& weak_ptr, std::nullptr_t) { 339 return !(weak_ptr == nullptr); 340 } 341 template <class T> 342 bool operator!=(std::nullptr_t, const WeakPtr<T>& weak_ptr) { 343 return weak_ptr != nullptr; 344 } 345 template <class T> 346 bool operator==(const WeakPtr<T>& weak_ptr, std::nullptr_t) { 347 return weak_ptr.get() == nullptr; 348 } 349 template <class T> 350 bool operator==(std::nullptr_t, const WeakPtr<T>& weak_ptr) { 351 return weak_ptr == nullptr; 352 } 353 354 namespace internal { 355 class BASE_EXPORT WeakPtrFactoryBase { 356 protected: 357 WeakPtrFactoryBase(uintptr_t ptr); 358 ~WeakPtrFactoryBase(); 359 internal::WeakReferenceOwner weak_reference_owner_; 360 uintptr_t ptr_; 361 }; 362 } // namespace internal 363 364 // A class may be composed of a WeakPtrFactory and thereby 365 // control how it exposes weak pointers to itself. This is helpful if you only 366 // need weak pointers within the implementation of a class. This class is also 367 // useful when working with primitive types. For example, you could have a 368 // WeakPtrFactory<bool> that is used to pass around a weak reference to a bool. 369 template <class T> 370 class WeakPtrFactory : public internal::WeakPtrFactoryBase { 371 public: 372 WeakPtrFactory() = delete; 373 374 explicit WeakPtrFactory(T* ptr) 375 : WeakPtrFactoryBase(reinterpret_cast<uintptr_t>(ptr)) {} 376 377 WeakPtrFactory(const WeakPtrFactory&) = delete; 378 WeakPtrFactory& operator=(const WeakPtrFactory&) = delete; 379 380 ~WeakPtrFactory() = default; 381 382 WeakPtr<const T> GetWeakPtr() const { 383 return WeakPtr<const T>(weak_reference_owner_.GetRef(), 384 reinterpret_cast<const T*>(ptr_)); 385 } 386 387 WeakPtr<T> GetWeakPtr() 388 requires(!std::is_const_v<T>) 389 { 390 return WeakPtr<T>(weak_reference_owner_.GetRef(), 391 reinterpret_cast<T*>(ptr_)); 392 } 393 394 WeakPtr<T> GetMutableWeakPtr() const 395 requires(!std::is_const_v<T>) 396 { 397 return WeakPtr<T>(weak_reference_owner_.GetRef(), 398 reinterpret_cast<T*>(ptr_)); 399 } 400 401 // Returns a smart pointer that is valid until the WeakPtrFactory is 402 // invalidated. Unlike WeakPtr, this smart pointer cannot be null, and cannot 403 // be checked to see if the WeakPtrFactory is invalidated. It's intended to 404 // express that the pointer will not (intentionally) outlive the `T` object it 405 // points to, and to crash safely in the case of a bug instead of causing a 406 // use-after-free. This type provides an alternative to WeakPtr to prevent 407 // use-after-free bugs without also introducing "fuzzy lifetimes" that can be 408 // checked for at runtime. 409 SafeRef<T> GetSafeRef() const { 410 return internal::MakeSafeRefFromWeakPtrInternals( 411 weak_reference_owner_.GetRef(), reinterpret_cast<T*>(ptr_)); 412 } 413 414 // Call this method to invalidate all existing weak pointers. 415 void InvalidateWeakPtrs() { 416 DCHECK(ptr_); 417 weak_reference_owner_.Invalidate(); 418 } 419 420 // Call this method to determine if any weak pointers exist. 421 bool HasWeakPtrs() const { 422 DCHECK(ptr_); 423 return weak_reference_owner_.HasRefs(); 424 } 425 426 // Rebind the factory to the current sequence. This allows creating a task 427 // queue and associated weak pointers on a different thread from the one they 428 // are used on. 429 void BindToCurrentSequence( 430 PassKey<sequence_manager::internal::TaskQueueImpl>) { 431 weak_reference_owner_.BindToCurrentSequence(); 432 } 433 }; 434 435 // A class may extend from SupportsWeakPtr to let others take weak pointers to 436 // it. This avoids the class itself implementing boilerplate to dispense weak 437 // pointers. However, since SupportsWeakPtr's destructor won't invalidate 438 // weak pointers to the class until after the derived class' members have been 439 // destroyed, its use can lead to subtle use-after-destroy issues. 440 template <class T> 441 class SupportsWeakPtr : public internal::SupportsWeakPtrBase { 442 public: 443 SupportsWeakPtr() = default; 444 445 SupportsWeakPtr(const SupportsWeakPtr&) = delete; 446 SupportsWeakPtr& operator=(const SupportsWeakPtr&) = delete; 447 448 WeakPtr<T> AsWeakPtr() { 449 return WeakPtr<T>(weak_reference_owner_.GetRef(), static_cast<T*>(this)); 450 } 451 452 protected: 453 ~SupportsWeakPtr() = default; 454 455 private: 456 internal::WeakReferenceOwner weak_reference_owner_; 457 }; 458 459 // Helper function that uses type deduction to safely return a WeakPtr<Derived> 460 // when Derived doesn't directly extend SupportsWeakPtr<Derived>, instead it 461 // extends a Base that extends SupportsWeakPtr<Base>. 462 // 463 // EXAMPLE: 464 // class Base : public base::SupportsWeakPtr<Producer> {}; 465 // class Derived : public Base {}; 466 // 467 // Derived derived; 468 // base::WeakPtr<Derived> ptr = base::AsWeakPtr(&derived); 469 // 470 // Note that the following doesn't work (invalid type conversion) since 471 // Derived::AsWeakPtr() is WeakPtr<Base> SupportsWeakPtr<Base>::AsWeakPtr(), 472 // and there's no way to safely cast WeakPtr<Base> to WeakPtr<Derived> at 473 // the caller. 474 // 475 // base::WeakPtr<Derived> ptr = derived.AsWeakPtr(); // Fails. 476 477 template <typename Derived> 478 WeakPtr<Derived> AsWeakPtr(Derived* t) { 479 return internal::SupportsWeakPtrBase::StaticAsWeakPtr<Derived>(t); 480 } 481 482 } // namespace base 483 484 #endif // BASE_MEMORY_WEAK_PTR_H_ 485