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