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 WeakPtr; 102 103 namespace internal { 104 // These classes are part of the WeakPtr implementation. 105 // DO NOT USE THESE CLASSES DIRECTLY YOURSELF. 106 107 class BASE_EXPORT TRIVIAL_ABI WeakReference { 108 public: 109 // Although Flag is bound to a specific SequencedTaskRunner, it may be 110 // deleted from another via base::WeakPtr::~WeakPtr(). 111 class BASE_EXPORT Flag : public RefCountedThreadSafe<Flag> { 112 public: 113 Flag(); 114 115 void Invalidate(); 116 bool IsValid() const; 117 118 bool MaybeValid() const; 119 120 #if DCHECK_IS_ON() 121 void DetachFromSequence(); 122 void BindToCurrentSequence(); 123 #endif 124 125 private: 126 friend class base::RefCountedThreadSafe<Flag>; 127 128 ~Flag(); 129 130 SEQUENCE_CHECKER(sequence_checker_); 131 AtomicFlag invalidated_; 132 }; 133 134 WeakReference(); 135 explicit WeakReference(const scoped_refptr<Flag>& flag); 136 ~WeakReference(); 137 138 WeakReference(const WeakReference& other); 139 WeakReference& operator=(const WeakReference& other); 140 141 WeakReference(WeakReference&& other) noexcept; 142 WeakReference& operator=(WeakReference&& other) noexcept; 143 144 void Reset(); 145 // Returns whether the WeakReference is valid, meaning the WeakPtrFactory has 146 // not invalidated the pointer. Unlike, RefIsMaybeValid(), this may only be 147 // called from the same sequence as where the WeakPtr was created. 148 bool IsValid() const; 149 // Returns false if the WeakReference is confirmed to be invalid. This call is 150 // safe to make from any thread, e.g. to optimize away unnecessary work, but 151 // RefIsValid() must always be called, on the correct sequence, before 152 // actually using the pointer. 153 // 154 // Warning: as with any object, this call is only thread-safe if the WeakPtr 155 // instance isn't being re-assigned or reset() racily with this call. 156 bool MaybeValid() const; 157 158 private: 159 scoped_refptr<const Flag> flag_; 160 }; 161 162 class BASE_EXPORT WeakReferenceOwner { 163 public: 164 WeakReferenceOwner(); 165 ~WeakReferenceOwner(); 166 167 WeakReference GetRef() const; 168 HasRefs()169 bool HasRefs() const { return !flag_->HasOneRef(); } 170 171 void Invalidate(); 172 void BindToCurrentSequence(); 173 174 private: 175 scoped_refptr<WeakReference::Flag> flag_; 176 }; 177 178 // Forward declaration from safe_ptr.h. 179 template <typename T> 180 SafeRef<T> MakeSafeRefFromWeakPtrInternals(internal::WeakReference&& ref, 181 T* ptr); 182 183 } // namespace internal 184 185 template <typename T> class WeakPtrFactory; 186 187 // The WeakPtr class holds a weak reference to |T*|. 188 // 189 // This class is designed to be used like a normal pointer. You should always 190 // null-test an object of this class before using it or invoking a method that 191 // may result in the underlying object being destroyed. 192 // 193 // EXAMPLE: 194 // 195 // class Foo { ... }; 196 // WeakPtr<Foo> foo; 197 // if (foo) 198 // foo->method(); 199 // 200 template <typename T> 201 class TRIVIAL_ABI WeakPtr { 202 public: 203 WeakPtr() = default; 204 // NOLINTNEXTLINE(google-explicit-constructor) WeakPtr(std::nullptr_t)205 WeakPtr(std::nullptr_t) {} 206 207 // Allow conversion from U to T provided U "is a" T. Note that this 208 // is separate from the (implicit) copy and move constructors. 209 template <typename U> requires(std::convertible_to<U *,T * >)210 requires(std::convertible_to<U*, T*>) 211 // NOLINTNEXTLINE(google-explicit-constructor) 212 WeakPtr(const WeakPtr<U>& other) : ref_(other.ref_), ptr_(other.ptr_) {} 213 template <typename U> requires(std::convertible_to<U *,T * >)214 requires(std::convertible_to<U*, T*>) 215 // NOLINTNEXTLINE(google-explicit-constructor) 216 WeakPtr& operator=(const WeakPtr<U>& other) { 217 ref_ = other.ref_; 218 ptr_ = other.ptr_; 219 return *this; 220 } 221 222 template <typename U> requires(std::convertible_to<U *,T * >)223 requires(std::convertible_to<U*, T*>) 224 // NOLINTNEXTLINE(google-explicit-constructor) 225 WeakPtr(WeakPtr<U>&& other) 226 : ref_(std::move(other.ref_)), ptr_(std::move(other.ptr_)) {} 227 template <typename U> requires(std::convertible_to<U *,T * >)228 requires(std::convertible_to<U*, T*>) 229 // NOLINTNEXTLINE(google-explicit-constructor) 230 WeakPtr& operator=(WeakPtr<U>&& other) { 231 ref_ = std::move(other.ref_); 232 ptr_ = std::move(other.ptr_); 233 return *this; 234 } 235 get()236 T* get() const { return ref_.IsValid() ? ptr_ : nullptr; } 237 238 // Provide access to the underlying T as a reference. Will CHECK() if the T 239 // pointee is no longer alive. 240 T& operator*() const { 241 CHECK(ref_.IsValid()); 242 return *ptr_; 243 } 244 245 // Used to call methods on the underlying T. Will CHECK() if the T pointee is 246 // no longer alive. 247 T* operator->() const { 248 CHECK(ref_.IsValid()); 249 return ptr_; 250 } 251 252 // Allow conditionals to test validity, e.g. if (weak_ptr) {...}; 253 explicit operator bool() const { return get() != nullptr; } 254 255 // Resets the WeakPtr to hold nothing. 256 // 257 // The `get()` method will return `nullptr` thereafter, and `MaybeValid()` 258 // will be `false`. reset()259 void reset() { 260 ref_.Reset(); 261 ptr_ = nullptr; 262 } 263 264 // Do not use this method. Almost all callers should instead use operator 265 // bool(). 266 // 267 // There are a few rare cases where the caller intentionally needs to check 268 // validity of a base::WeakPtr on a sequence different from the bound sequence 269 // as an unavoidable performance optimization. This is the only valid use-case 270 // for this method. See 271 // https://docs.google.com/document/d/1IGzq9Nx69GS_2iynGmPWo5sFAD2DcCyBY1zIvZwF7k8 272 // for details. 273 // 274 // Returns false if the WeakPtr is confirmed to be invalid. This call is safe 275 // to make from any thread, e.g. to optimize away unnecessary work, but 276 // RefIsValid() must always be called, on the correct sequence, before 277 // actually using the pointer. 278 // 279 // Warning: as with any object, this call is only thread-safe if the WeakPtr 280 // instance isn't being re-assigned or reset() racily with this call. MaybeValid()281 bool MaybeValid() const { return ref_.MaybeValid(); } 282 283 // Returns whether the object |this| points to has been invalidated. This can 284 // be used to distinguish a WeakPtr to a destroyed object from one that has 285 // been explicitly set to null. WasInvalidated()286 bool WasInvalidated() const { return ptr_ && !ref_.IsValid(); } 287 288 private: 289 template <typename U> friend class WeakPtr; 290 friend class WeakPtrFactory<T>; 291 friend class WeakPtrFactory<std::remove_const_t<T>>; 292 WeakPtr(internal::WeakReference && ref,T * ptr)293 WeakPtr(internal::WeakReference&& ref, T* ptr) 294 : ref_(std::move(ref)), ptr_(ptr) { 295 DCHECK(ptr); 296 } 297 CloneWeakReference()298 internal::WeakReference CloneWeakReference() const { return ref_; } 299 300 internal::WeakReference ref_; 301 302 // This pointer is only valid when ref_.is_valid() is true. Otherwise, its 303 // value is undefined (as opposed to nullptr). The pointer is allowed to 304 // dangle as we verify its liveness through `ref_` before allowing access to 305 // the pointee. We don't use raw_ptr<T> here to prevent WeakPtr from keeping 306 // the memory allocation in quarantine, as it can't be accessed through the 307 // WeakPtr. 308 RAW_PTR_EXCLUSION T* ptr_ = nullptr; 309 }; 310 311 // Allow callers to compare WeakPtrs against nullptr to test validity. 312 template <class T> 313 bool operator!=(const WeakPtr<T>& weak_ptr, std::nullptr_t) { 314 return !(weak_ptr == nullptr); 315 } 316 template <class T> 317 bool operator!=(std::nullptr_t, const WeakPtr<T>& weak_ptr) { 318 return weak_ptr != nullptr; 319 } 320 template <class T> 321 bool operator==(const WeakPtr<T>& weak_ptr, std::nullptr_t) { 322 return weak_ptr.get() == nullptr; 323 } 324 template <class T> 325 bool operator==(std::nullptr_t, const WeakPtr<T>& weak_ptr) { 326 return weak_ptr == nullptr; 327 } 328 329 namespace internal { 330 class BASE_EXPORT WeakPtrFactoryBase { 331 protected: 332 WeakPtrFactoryBase(uintptr_t ptr); 333 ~WeakPtrFactoryBase(); 334 internal::WeakReferenceOwner weak_reference_owner_; 335 uintptr_t ptr_; 336 }; 337 } // namespace internal 338 339 namespace subtle { 340 341 // Restricts access to WeakPtrFactory::BindToCurrentSequence() to authorized 342 // callers. 343 class BASE_EXPORT BindWeakPtrFactoryPassKey { 344 private: 345 BindWeakPtrFactoryPassKey() = default; 346 347 friend class BindWeakPtrFactoryForTesting; 348 friend class performance_manager::FrameNodeImpl; 349 friend class performance_manager::PageNodeImpl; 350 friend class performance_manager::ProcessNodeImpl; 351 friend class performance_manager::WorkerNodeImpl; 352 friend class sequence_manager::internal::TaskQueueImpl; 353 }; 354 355 } // namespace subtle 356 357 // A class may be composed of a WeakPtrFactory and thereby 358 // control how it exposes weak pointers to itself. This is helpful if you only 359 // need weak pointers within the implementation of a class. This class is also 360 // useful when working with primitive types. For example, you could have a 361 // WeakPtrFactory<bool> that is used to pass around a weak reference to a bool. 362 template <class T> 363 class WeakPtrFactory : public internal::WeakPtrFactoryBase { 364 public: 365 WeakPtrFactory() = delete; 366 WeakPtrFactory(T * ptr)367 explicit WeakPtrFactory(T* ptr) 368 : WeakPtrFactoryBase(reinterpret_cast<uintptr_t>(ptr)) {} 369 370 WeakPtrFactory(const WeakPtrFactory&) = delete; 371 WeakPtrFactory& operator=(const WeakPtrFactory&) = delete; 372 373 ~WeakPtrFactory() = default; 374 GetWeakPtr()375 WeakPtr<const T> GetWeakPtr() const { 376 return WeakPtr<const T>(weak_reference_owner_.GetRef(), 377 reinterpret_cast<const T*>(ptr_)); 378 } 379 GetWeakPtr()380 WeakPtr<T> GetWeakPtr() 381 requires(!std::is_const_v<T>) 382 { 383 return WeakPtr<T>(weak_reference_owner_.GetRef(), 384 reinterpret_cast<T*>(ptr_)); 385 } 386 GetMutableWeakPtr()387 WeakPtr<T> GetMutableWeakPtr() const 388 requires(!std::is_const_v<T>) 389 { 390 return WeakPtr<T>(weak_reference_owner_.GetRef(), 391 reinterpret_cast<T*>(ptr_)); 392 } 393 394 // Returns a smart pointer that is valid until the WeakPtrFactory is 395 // invalidated. Unlike WeakPtr, this smart pointer cannot be null, and cannot 396 // be checked to see if the WeakPtrFactory is invalidated. It's intended to 397 // express that the pointer will not (intentionally) outlive the `T` object it 398 // points to, and to crash safely in the case of a bug instead of causing a 399 // use-after-free. This type provides an alternative to WeakPtr to prevent 400 // use-after-free bugs without also introducing "fuzzy lifetimes" that can be 401 // checked for at runtime. GetSafeRef()402 SafeRef<T> GetSafeRef() const { 403 return internal::MakeSafeRefFromWeakPtrInternals( 404 weak_reference_owner_.GetRef(), reinterpret_cast<T*>(ptr_)); 405 } 406 407 // Call this method to invalidate all existing weak pointers. InvalidateWeakPtrs()408 void InvalidateWeakPtrs() { 409 DCHECK(ptr_); 410 weak_reference_owner_.Invalidate(); 411 } 412 413 // Call this method to determine if any weak pointers exist. HasWeakPtrs()414 bool HasWeakPtrs() const { 415 DCHECK(ptr_); 416 return weak_reference_owner_.HasRefs(); 417 } 418 419 // Rebind the factory to the current sequence. This allows creating an object 420 // and associated weak pointers on a different thread from the one they are 421 // used on. BindToCurrentSequence(subtle::BindWeakPtrFactoryPassKey)422 void BindToCurrentSequence(subtle::BindWeakPtrFactoryPassKey) { 423 weak_reference_owner_.BindToCurrentSequence(); 424 } 425 }; 426 427 } // namespace base 428 429 #endif // BASE_MEMORY_WEAK_PTR_H_ 430