1*d9f75844SAndroid Build Coastguard Worker /* 2*d9f75844SAndroid Build Coastguard Worker * Copyright 2016 The WebRTC Project Authors. All rights reserved. 3*d9f75844SAndroid Build Coastguard Worker * 4*d9f75844SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license 5*d9f75844SAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source 6*d9f75844SAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found 7*d9f75844SAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may 8*d9f75844SAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree. 9*d9f75844SAndroid Build Coastguard Worker */ 10*d9f75844SAndroid Build Coastguard Worker 11*d9f75844SAndroid Build Coastguard Worker #ifndef RTC_BASE_WEAK_PTR_H_ 12*d9f75844SAndroid Build Coastguard Worker #define RTC_BASE_WEAK_PTR_H_ 13*d9f75844SAndroid Build Coastguard Worker 14*d9f75844SAndroid Build Coastguard Worker #include <memory> 15*d9f75844SAndroid Build Coastguard Worker #include <utility> 16*d9f75844SAndroid Build Coastguard Worker 17*d9f75844SAndroid Build Coastguard Worker #include "api/scoped_refptr.h" 18*d9f75844SAndroid Build Coastguard Worker #include "api/sequence_checker.h" 19*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/ref_count.h" 20*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/ref_counted_object.h" 21*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/system/no_unique_address.h" 22*d9f75844SAndroid Build Coastguard Worker 23*d9f75844SAndroid Build Coastguard Worker // The implementation is borrowed from chromium except that it does not 24*d9f75844SAndroid Build Coastguard Worker // implement SupportsWeakPtr. 25*d9f75844SAndroid Build Coastguard Worker 26*d9f75844SAndroid Build Coastguard Worker // Weak pointers are pointers to an object that do not affect its lifetime, 27*d9f75844SAndroid Build Coastguard Worker // and which may be invalidated (i.e. reset to nullptr) by the object, or its 28*d9f75844SAndroid Build Coastguard Worker // owner, at any time, most commonly when the object is about to be deleted. 29*d9f75844SAndroid Build Coastguard Worker 30*d9f75844SAndroid Build Coastguard Worker // Weak pointers are useful when an object needs to be accessed safely by one 31*d9f75844SAndroid Build Coastguard Worker // or more objects other than its owner, and those callers can cope with the 32*d9f75844SAndroid Build Coastguard Worker // object vanishing and e.g. tasks posted to it being silently dropped. 33*d9f75844SAndroid Build Coastguard Worker // Reference-counting such an object would complicate the ownership graph and 34*d9f75844SAndroid Build Coastguard Worker // make it harder to reason about the object's lifetime. 35*d9f75844SAndroid Build Coastguard Worker 36*d9f75844SAndroid Build Coastguard Worker // EXAMPLE: 37*d9f75844SAndroid Build Coastguard Worker // 38*d9f75844SAndroid Build Coastguard Worker // class Controller { 39*d9f75844SAndroid Build Coastguard Worker // public: 40*d9f75844SAndroid Build Coastguard Worker // Controller() : weak_factory_(this) {} 41*d9f75844SAndroid Build Coastguard Worker // void SpawnWorker() { Worker::StartNew(weak_factory_.GetWeakPtr()); } 42*d9f75844SAndroid Build Coastguard Worker // void WorkComplete(const Result& result) { ... } 43*d9f75844SAndroid Build Coastguard Worker // private: 44*d9f75844SAndroid Build Coastguard Worker // // Member variables should appear before the WeakPtrFactory, to ensure 45*d9f75844SAndroid Build Coastguard Worker // // that any WeakPtrs to Controller are invalidated before its members 46*d9f75844SAndroid Build Coastguard Worker // // variable's destructors are executed, rendering them invalid. 47*d9f75844SAndroid Build Coastguard Worker // WeakPtrFactory<Controller> weak_factory_; 48*d9f75844SAndroid Build Coastguard Worker // }; 49*d9f75844SAndroid Build Coastguard Worker // 50*d9f75844SAndroid Build Coastguard Worker // class Worker { 51*d9f75844SAndroid Build Coastguard Worker // public: 52*d9f75844SAndroid Build Coastguard Worker // static void StartNew(const WeakPtr<Controller>& controller) { 53*d9f75844SAndroid Build Coastguard Worker // Worker* worker = new Worker(controller); 54*d9f75844SAndroid Build Coastguard Worker // // Kick off asynchronous processing... 55*d9f75844SAndroid Build Coastguard Worker // } 56*d9f75844SAndroid Build Coastguard Worker // private: 57*d9f75844SAndroid Build Coastguard Worker // Worker(const WeakPtr<Controller>& controller) 58*d9f75844SAndroid Build Coastguard Worker // : controller_(controller) {} 59*d9f75844SAndroid Build Coastguard Worker // void DidCompleteAsynchronousProcessing(const Result& result) { 60*d9f75844SAndroid Build Coastguard Worker // if (controller_) 61*d9f75844SAndroid Build Coastguard Worker // controller_->WorkComplete(result); 62*d9f75844SAndroid Build Coastguard Worker // } 63*d9f75844SAndroid Build Coastguard Worker // WeakPtr<Controller> controller_; 64*d9f75844SAndroid Build Coastguard Worker // }; 65*d9f75844SAndroid Build Coastguard Worker // 66*d9f75844SAndroid Build Coastguard Worker // With this implementation a caller may use SpawnWorker() to dispatch multiple 67*d9f75844SAndroid Build Coastguard Worker // Workers and subsequently delete the Controller, without waiting for all 68*d9f75844SAndroid Build Coastguard Worker // Workers to have completed. 69*d9f75844SAndroid Build Coastguard Worker 70*d9f75844SAndroid Build Coastguard Worker // ------------------------- IMPORTANT: Thread-safety ------------------------- 71*d9f75844SAndroid Build Coastguard Worker 72*d9f75844SAndroid Build Coastguard Worker // Weak pointers may be passed safely between threads, but must always be 73*d9f75844SAndroid Build Coastguard Worker // dereferenced and invalidated on the same TaskQueue or thread, otherwise 74*d9f75844SAndroid Build Coastguard Worker // checking the pointer would be racey. 75*d9f75844SAndroid Build Coastguard Worker // 76*d9f75844SAndroid Build Coastguard Worker // To ensure correct use, the first time a WeakPtr issued by a WeakPtrFactory 77*d9f75844SAndroid Build Coastguard Worker // is dereferenced, the factory and its WeakPtrs become bound to the calling 78*d9f75844SAndroid Build Coastguard Worker // TaskQueue/thread, and cannot be dereferenced or 79*d9f75844SAndroid Build Coastguard Worker // invalidated on any other TaskQueue/thread. Bound WeakPtrs can still be handed 80*d9f75844SAndroid Build Coastguard Worker // off to other TaskQueues, e.g. to use to post tasks back to object on the 81*d9f75844SAndroid Build Coastguard Worker // bound sequence. 82*d9f75844SAndroid Build Coastguard Worker // 83*d9f75844SAndroid Build Coastguard Worker // Thus, at least one WeakPtr object must exist and have been dereferenced on 84*d9f75844SAndroid Build Coastguard Worker // the correct thread to enforce that other WeakPtr objects will enforce they 85*d9f75844SAndroid Build Coastguard Worker // are used on the desired thread. 86*d9f75844SAndroid Build Coastguard Worker 87*d9f75844SAndroid Build Coastguard Worker namespace rtc { 88*d9f75844SAndroid Build Coastguard Worker 89*d9f75844SAndroid Build Coastguard Worker namespace internal { 90*d9f75844SAndroid Build Coastguard Worker 91*d9f75844SAndroid Build Coastguard Worker class WeakReference { 92*d9f75844SAndroid Build Coastguard Worker public: 93*d9f75844SAndroid Build Coastguard Worker // Although Flag is bound to a specific sequence, it may be 94*d9f75844SAndroid Build Coastguard Worker // deleted from another via base::WeakPtr::~WeakPtr(). 95*d9f75844SAndroid Build Coastguard Worker class Flag : public RefCountInterface { 96*d9f75844SAndroid Build Coastguard Worker public: 97*d9f75844SAndroid Build Coastguard Worker Flag(); 98*d9f75844SAndroid Build Coastguard Worker 99*d9f75844SAndroid Build Coastguard Worker void Invalidate(); 100*d9f75844SAndroid Build Coastguard Worker bool IsValid() const; 101*d9f75844SAndroid Build Coastguard Worker 102*d9f75844SAndroid Build Coastguard Worker private: 103*d9f75844SAndroid Build Coastguard Worker friend class RefCountedObject<Flag>; 104*d9f75844SAndroid Build Coastguard Worker 105*d9f75844SAndroid Build Coastguard Worker ~Flag() override; 106*d9f75844SAndroid Build Coastguard Worker 107*d9f75844SAndroid Build Coastguard Worker RTC_NO_UNIQUE_ADDRESS ::webrtc::SequenceChecker checker_; 108*d9f75844SAndroid Build Coastguard Worker bool is_valid_; 109*d9f75844SAndroid Build Coastguard Worker }; 110*d9f75844SAndroid Build Coastguard Worker 111*d9f75844SAndroid Build Coastguard Worker WeakReference(); 112*d9f75844SAndroid Build Coastguard Worker explicit WeakReference(const Flag* flag); 113*d9f75844SAndroid Build Coastguard Worker ~WeakReference(); 114*d9f75844SAndroid Build Coastguard Worker 115*d9f75844SAndroid Build Coastguard Worker WeakReference(WeakReference&& other); 116*d9f75844SAndroid Build Coastguard Worker WeakReference(const WeakReference& other); 117*d9f75844SAndroid Build Coastguard Worker WeakReference& operator=(WeakReference&& other) = default; 118*d9f75844SAndroid Build Coastguard Worker WeakReference& operator=(const WeakReference& other) = default; 119*d9f75844SAndroid Build Coastguard Worker 120*d9f75844SAndroid Build Coastguard Worker bool is_valid() const; 121*d9f75844SAndroid Build Coastguard Worker 122*d9f75844SAndroid Build Coastguard Worker private: 123*d9f75844SAndroid Build Coastguard Worker scoped_refptr<const Flag> flag_; 124*d9f75844SAndroid Build Coastguard Worker }; 125*d9f75844SAndroid Build Coastguard Worker 126*d9f75844SAndroid Build Coastguard Worker class WeakReferenceOwner { 127*d9f75844SAndroid Build Coastguard Worker public: 128*d9f75844SAndroid Build Coastguard Worker WeakReferenceOwner(); 129*d9f75844SAndroid Build Coastguard Worker ~WeakReferenceOwner(); 130*d9f75844SAndroid Build Coastguard Worker 131*d9f75844SAndroid Build Coastguard Worker WeakReference GetRef() const; 132*d9f75844SAndroid Build Coastguard Worker HasRefs()133*d9f75844SAndroid Build Coastguard Worker bool HasRefs() const { return flag_.get() && !flag_->HasOneRef(); } 134*d9f75844SAndroid Build Coastguard Worker 135*d9f75844SAndroid Build Coastguard Worker void Invalidate(); 136*d9f75844SAndroid Build Coastguard Worker 137*d9f75844SAndroid Build Coastguard Worker private: 138*d9f75844SAndroid Build Coastguard Worker mutable scoped_refptr<RefCountedObject<WeakReference::Flag>> flag_; 139*d9f75844SAndroid Build Coastguard Worker }; 140*d9f75844SAndroid Build Coastguard Worker 141*d9f75844SAndroid Build Coastguard Worker // This class simplifies the implementation of WeakPtr's type conversion 142*d9f75844SAndroid Build Coastguard Worker // constructor by avoiding the need for a public accessor for ref_. A 143*d9f75844SAndroid Build Coastguard Worker // WeakPtr<T> cannot access the private members of WeakPtr<U>, so this 144*d9f75844SAndroid Build Coastguard Worker // base class gives us a way to access ref_ in a protected fashion. 145*d9f75844SAndroid Build Coastguard Worker class WeakPtrBase { 146*d9f75844SAndroid Build Coastguard Worker public: 147*d9f75844SAndroid Build Coastguard Worker WeakPtrBase(); 148*d9f75844SAndroid Build Coastguard Worker ~WeakPtrBase(); 149*d9f75844SAndroid Build Coastguard Worker 150*d9f75844SAndroid Build Coastguard Worker WeakPtrBase(const WeakPtrBase& other) = default; 151*d9f75844SAndroid Build Coastguard Worker WeakPtrBase(WeakPtrBase&& other) = default; 152*d9f75844SAndroid Build Coastguard Worker WeakPtrBase& operator=(const WeakPtrBase& other) = default; 153*d9f75844SAndroid Build Coastguard Worker WeakPtrBase& operator=(WeakPtrBase&& other) = default; 154*d9f75844SAndroid Build Coastguard Worker 155*d9f75844SAndroid Build Coastguard Worker protected: 156*d9f75844SAndroid Build Coastguard Worker explicit WeakPtrBase(const WeakReference& ref); 157*d9f75844SAndroid Build Coastguard Worker 158*d9f75844SAndroid Build Coastguard Worker WeakReference ref_; 159*d9f75844SAndroid Build Coastguard Worker }; 160*d9f75844SAndroid Build Coastguard Worker 161*d9f75844SAndroid Build Coastguard Worker } // namespace internal 162*d9f75844SAndroid Build Coastguard Worker 163*d9f75844SAndroid Build Coastguard Worker template <typename T> 164*d9f75844SAndroid Build Coastguard Worker class WeakPtrFactory; 165*d9f75844SAndroid Build Coastguard Worker 166*d9f75844SAndroid Build Coastguard Worker template <typename T> 167*d9f75844SAndroid Build Coastguard Worker class WeakPtr : public internal::WeakPtrBase { 168*d9f75844SAndroid Build Coastguard Worker public: WeakPtr()169*d9f75844SAndroid Build Coastguard Worker WeakPtr() : ptr_(nullptr) {} 170*d9f75844SAndroid Build Coastguard Worker 171*d9f75844SAndroid Build Coastguard Worker // Allow conversion from U to T provided U "is a" T. Note that this 172*d9f75844SAndroid Build Coastguard Worker // is separate from the (implicit) copy and move constructors. 173*d9f75844SAndroid Build Coastguard Worker template <typename U> WeakPtr(const WeakPtr<U> & other)174*d9f75844SAndroid Build Coastguard Worker WeakPtr(const WeakPtr<U>& other) 175*d9f75844SAndroid Build Coastguard Worker : internal::WeakPtrBase(other), ptr_(other.ptr_) {} 176*d9f75844SAndroid Build Coastguard Worker template <typename U> WeakPtr(WeakPtr<U> && other)177*d9f75844SAndroid Build Coastguard Worker WeakPtr(WeakPtr<U>&& other) 178*d9f75844SAndroid Build Coastguard Worker : internal::WeakPtrBase(std::move(other)), ptr_(other.ptr_) {} 179*d9f75844SAndroid Build Coastguard Worker get()180*d9f75844SAndroid Build Coastguard Worker T* get() const { return ref_.is_valid() ? ptr_ : nullptr; } 181*d9f75844SAndroid Build Coastguard Worker 182*d9f75844SAndroid Build Coastguard Worker T& operator*() const { 183*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(get() != nullptr); 184*d9f75844SAndroid Build Coastguard Worker return *get(); 185*d9f75844SAndroid Build Coastguard Worker } 186*d9f75844SAndroid Build Coastguard Worker T* operator->() const { 187*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(get() != nullptr); 188*d9f75844SAndroid Build Coastguard Worker return get(); 189*d9f75844SAndroid Build Coastguard Worker } 190*d9f75844SAndroid Build Coastguard Worker reset()191*d9f75844SAndroid Build Coastguard Worker void reset() { 192*d9f75844SAndroid Build Coastguard Worker ref_ = internal::WeakReference(); 193*d9f75844SAndroid Build Coastguard Worker ptr_ = nullptr; 194*d9f75844SAndroid Build Coastguard Worker } 195*d9f75844SAndroid Build Coastguard Worker 196*d9f75844SAndroid Build Coastguard Worker // Allow conditionals to test validity, e.g. if (weak_ptr) {...}; 197*d9f75844SAndroid Build Coastguard Worker explicit operator bool() const { return get() != nullptr; } 198*d9f75844SAndroid Build Coastguard Worker 199*d9f75844SAndroid Build Coastguard Worker private: 200*d9f75844SAndroid Build Coastguard Worker template <typename U> 201*d9f75844SAndroid Build Coastguard Worker friend class WeakPtr; 202*d9f75844SAndroid Build Coastguard Worker friend class WeakPtrFactory<T>; 203*d9f75844SAndroid Build Coastguard Worker WeakPtr(const internal::WeakReference & ref,T * ptr)204*d9f75844SAndroid Build Coastguard Worker WeakPtr(const internal::WeakReference& ref, T* ptr) 205*d9f75844SAndroid Build Coastguard Worker : internal::WeakPtrBase(ref), ptr_(ptr) {} 206*d9f75844SAndroid Build Coastguard Worker 207*d9f75844SAndroid Build Coastguard Worker // This pointer is only valid when ref_.is_valid() is true. Otherwise, its 208*d9f75844SAndroid Build Coastguard Worker // value is undefined (as opposed to nullptr). 209*d9f75844SAndroid Build Coastguard Worker T* ptr_; 210*d9f75844SAndroid Build Coastguard Worker }; 211*d9f75844SAndroid Build Coastguard Worker 212*d9f75844SAndroid Build Coastguard Worker // Allow callers to compare WeakPtrs against nullptr to test validity. 213*d9f75844SAndroid Build Coastguard Worker template <class T> 214*d9f75844SAndroid Build Coastguard Worker bool operator!=(const WeakPtr<T>& weak_ptr, std::nullptr_t) { 215*d9f75844SAndroid Build Coastguard Worker return !(weak_ptr == nullptr); 216*d9f75844SAndroid Build Coastguard Worker } 217*d9f75844SAndroid Build Coastguard Worker template <class T> 218*d9f75844SAndroid Build Coastguard Worker bool operator!=(std::nullptr_t, const WeakPtr<T>& weak_ptr) { 219*d9f75844SAndroid Build Coastguard Worker return weak_ptr != nullptr; 220*d9f75844SAndroid Build Coastguard Worker } 221*d9f75844SAndroid Build Coastguard Worker template <class T> 222*d9f75844SAndroid Build Coastguard Worker bool operator==(const WeakPtr<T>& weak_ptr, std::nullptr_t) { 223*d9f75844SAndroid Build Coastguard Worker return weak_ptr.get() == nullptr; 224*d9f75844SAndroid Build Coastguard Worker } 225*d9f75844SAndroid Build Coastguard Worker template <class T> 226*d9f75844SAndroid Build Coastguard Worker bool operator==(std::nullptr_t, const WeakPtr<T>& weak_ptr) { 227*d9f75844SAndroid Build Coastguard Worker return weak_ptr == nullptr; 228*d9f75844SAndroid Build Coastguard Worker } 229*d9f75844SAndroid Build Coastguard Worker 230*d9f75844SAndroid Build Coastguard Worker // A class may be composed of a WeakPtrFactory and thereby 231*d9f75844SAndroid Build Coastguard Worker // control how it exposes weak pointers to itself. This is helpful if you only 232*d9f75844SAndroid Build Coastguard Worker // need weak pointers within the implementation of a class. This class is also 233*d9f75844SAndroid Build Coastguard Worker // useful when working with primitive types. For example, you could have a 234*d9f75844SAndroid Build Coastguard Worker // WeakPtrFactory<bool> that is used to pass around a weak reference to a bool. 235*d9f75844SAndroid Build Coastguard Worker 236*d9f75844SAndroid Build Coastguard Worker // Note that GetWeakPtr must be called on one and only one TaskQueue or thread 237*d9f75844SAndroid Build Coastguard Worker // and the WeakPtr must only be dereferenced and invalidated on that same 238*d9f75844SAndroid Build Coastguard Worker // TaskQueue/thread. A WeakPtr instance can be copied and posted to other 239*d9f75844SAndroid Build Coastguard Worker // sequences though as long as it is not dereferenced (WeakPtr<T>::get()). 240*d9f75844SAndroid Build Coastguard Worker template <class T> 241*d9f75844SAndroid Build Coastguard Worker class WeakPtrFactory { 242*d9f75844SAndroid Build Coastguard Worker public: WeakPtrFactory(T * ptr)243*d9f75844SAndroid Build Coastguard Worker explicit WeakPtrFactory(T* ptr) : ptr_(ptr) {} 244*d9f75844SAndroid Build Coastguard Worker 245*d9f75844SAndroid Build Coastguard Worker WeakPtrFactory() = delete; 246*d9f75844SAndroid Build Coastguard Worker WeakPtrFactory(const WeakPtrFactory&) = delete; 247*d9f75844SAndroid Build Coastguard Worker WeakPtrFactory& operator=(const WeakPtrFactory&) = delete; 248*d9f75844SAndroid Build Coastguard Worker ~WeakPtrFactory()249*d9f75844SAndroid Build Coastguard Worker ~WeakPtrFactory() { ptr_ = nullptr; } 250*d9f75844SAndroid Build Coastguard Worker GetWeakPtr()251*d9f75844SAndroid Build Coastguard Worker WeakPtr<T> GetWeakPtr() { 252*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(ptr_); 253*d9f75844SAndroid Build Coastguard Worker return WeakPtr<T>(weak_reference_owner_.GetRef(), ptr_); 254*d9f75844SAndroid Build Coastguard Worker } 255*d9f75844SAndroid Build Coastguard Worker 256*d9f75844SAndroid Build Coastguard Worker // Call this method to invalidate all existing weak pointers. InvalidateWeakPtrs()257*d9f75844SAndroid Build Coastguard Worker void InvalidateWeakPtrs() { 258*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(ptr_); 259*d9f75844SAndroid Build Coastguard Worker weak_reference_owner_.Invalidate(); 260*d9f75844SAndroid Build Coastguard Worker } 261*d9f75844SAndroid Build Coastguard Worker 262*d9f75844SAndroid Build Coastguard Worker // Call this method to determine if any weak pointers exist. HasWeakPtrs()263*d9f75844SAndroid Build Coastguard Worker bool HasWeakPtrs() const { 264*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(ptr_); 265*d9f75844SAndroid Build Coastguard Worker return weak_reference_owner_.HasRefs(); 266*d9f75844SAndroid Build Coastguard Worker } 267*d9f75844SAndroid Build Coastguard Worker 268*d9f75844SAndroid Build Coastguard Worker private: 269*d9f75844SAndroid Build Coastguard Worker internal::WeakReferenceOwner weak_reference_owner_; 270*d9f75844SAndroid Build Coastguard Worker T* ptr_; 271*d9f75844SAndroid Build Coastguard Worker }; 272*d9f75844SAndroid Build Coastguard Worker 273*d9f75844SAndroid Build Coastguard Worker } // namespace rtc 274*d9f75844SAndroid Build Coastguard Worker 275*d9f75844SAndroid Build Coastguard Worker #endif // RTC_BASE_WEAK_PTR_H_ 276