1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 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 help in cases where you have many objects referring back to a 6 // shared object and you wish for the lifetime of the shared object to not be 7 // bound to the lifetime of the referrers. In other words, this is useful when 8 // reference counting is not a good fit. 9 // 10 // A common alternative to weak pointers is to have the shared object hold a 11 // list of all referrers, and then when the shared object is destroyed, it 12 // calls a method on the referrers to tell them to drop their references. This 13 // approach also requires the referrers to tell the shared object when they get 14 // destroyed so that the shared object can remove the referrer from its list of 15 // referrers. Such a solution works, but it is a bit complex. 16 // 17 // EXAMPLE: 18 // 19 // class Controller : public SupportsWeakPtr<Controller> { 20 // public: 21 // void SpawnWorker() { Worker::StartNew(AsWeakPtr()); } 22 // void WorkComplete(const Result& result) { ... } 23 // }; 24 // 25 // class Worker { 26 // public: 27 // static void StartNew(const WeakPtr<Controller>& controller) { 28 // Worker* worker = new Worker(controller); 29 // // Kick off asynchronous processing... 30 // } 31 // private: 32 // Worker(const WeakPtr<Controller>& controller) 33 // : controller_(controller) {} 34 // void DidCompleteAsynchronousProcessing(const Result& result) { 35 // if (controller_) 36 // controller_->WorkComplete(result); 37 // } 38 // WeakPtr<Controller> controller_; 39 // }; 40 // 41 // Given the above classes, a consumer may allocate a Controller object, call 42 // SpawnWorker several times, and then destroy the Controller object before all 43 // of the workers have completed. Because the Worker class only holds a weak 44 // pointer to the Controller, we don't have to worry about the Worker 45 // dereferencing the Controller back pointer after the Controller has been 46 // destroyed. 47 // 48 // WARNING: weak pointers are not threadsafe!!! You must only use a WeakPtr 49 // instance on thread where it was created. 50 51 #ifndef BASE_WEAK_PTR_H_ 52 #define BASE_WEAK_PTR_H_ 53 54 #include "base/logging.h" 55 #include "base/non_thread_safe.h" 56 #include "base/ref_counted.h" 57 58 namespace base { 59 60 namespace internal { 61 // These classes are part of the WeakPtr implementation. 62 // DO NOT USE THESE CLASSES DIRECTLY YOURSELF. 63 64 class WeakReference { 65 public: 66 class Flag : public RefCounted<Flag>, public NonThreadSafe { 67 public: Flag(Flag ** handle)68 Flag(Flag** handle) : handle_(handle) { 69 } 70 ~Flag()71 ~Flag() { 72 if (handle_) 73 *handle_ = NULL; 74 } 75 AddRef()76 void AddRef() { 77 DCHECK(CalledOnValidThread()); 78 RefCounted<Flag>::AddRef(); 79 } 80 Release()81 void Release() { 82 DCHECK(CalledOnValidThread()); 83 RefCounted<Flag>::Release(); 84 } 85 Invalidate()86 void Invalidate() { handle_ = NULL; } is_valid()87 bool is_valid() const { return handle_ != NULL; } 88 89 private: 90 Flag** handle_; 91 }; 92 WeakReference()93 WeakReference() {} WeakReference(Flag * flag)94 WeakReference(Flag* flag) : flag_(flag) {} 95 is_valid()96 bool is_valid() const { return flag_ && flag_->is_valid(); } 97 98 private: 99 scoped_refptr<Flag> flag_; 100 }; 101 102 class WeakReferenceOwner { 103 public: WeakReferenceOwner()104 WeakReferenceOwner() : flag_(NULL) { 105 } 106 ~WeakReferenceOwner()107 ~WeakReferenceOwner() { 108 Invalidate(); 109 } 110 GetRef()111 WeakReference GetRef() const { 112 if (!flag_) 113 flag_ = new WeakReference::Flag(&flag_); 114 return WeakReference(flag_); 115 } 116 HasRefs()117 bool HasRefs() const { 118 return flag_ != NULL; 119 } 120 Invalidate()121 void Invalidate() { 122 if (flag_) { 123 flag_->Invalidate(); 124 flag_ = NULL; 125 } 126 } 127 128 private: 129 mutable WeakReference::Flag* flag_; 130 }; 131 132 // This class simplifies the implementation of WeakPtr's type conversion 133 // constructor by avoiding the need for a public accessor for ref_. A 134 // WeakPtr<T> cannot access the private members of WeakPtr<U>, so this 135 // base class gives us a way to access ref_ in a protected fashion. 136 class WeakPtrBase { 137 public: WeakPtrBase()138 WeakPtrBase() { 139 } 140 141 protected: WeakPtrBase(const WeakReference & ref)142 WeakPtrBase(const WeakReference& ref) : ref_(ref) { 143 } 144 145 WeakReference ref_; 146 }; 147 148 } // namespace internal 149 150 template <typename T> class SupportsWeakPtr; 151 template <typename T> class WeakPtrFactory; 152 153 // The WeakPtr class holds a weak reference to |T*|. 154 // 155 // This class is designed to be used like a normal pointer. You should always 156 // null-test an object of this class before using it or invoking a method that 157 // may result in the underlying object being destroyed. 158 // 159 // EXAMPLE: 160 // 161 // class Foo { ... }; 162 // WeakPtr<Foo> foo; 163 // if (foo) 164 // foo->method(); 165 // 166 template <typename T> 167 class WeakPtr : public internal::WeakPtrBase { 168 public: WeakPtr()169 WeakPtr() : ptr_(NULL) { 170 } 171 172 // Allow conversion from U to T provided U "is a" T. 173 template <typename U> WeakPtr(const WeakPtr<U> & other)174 WeakPtr(const WeakPtr<U>& other) : WeakPtrBase(other), ptr_(other.get()) { 175 } 176 get()177 T* get() const { return ref_.is_valid() ? ptr_ : NULL; } 178 operator T*() const { return get(); } 179 180 T* operator*() const { 181 DCHECK(get() != NULL); 182 return *get(); 183 } 184 T* operator->() const { 185 DCHECK(get() != NULL); 186 return get(); 187 } 188 reset()189 void reset() { 190 ref_ = internal::WeakReference(); 191 ptr_ = NULL; 192 } 193 194 private: 195 friend class SupportsWeakPtr<T>; 196 friend class WeakPtrFactory<T>; 197 WeakPtr(const internal::WeakReference & ref,T * ptr)198 WeakPtr(const internal::WeakReference& ref, T* ptr) 199 : WeakPtrBase(ref), ptr_(ptr) { 200 } 201 202 // This pointer is only valid when ref_.is_valid() is true. Otherwise, its 203 // value is undefined (as opposed to NULL). 204 T* ptr_; 205 }; 206 207 // A class may extend from SupportsWeakPtr to expose weak pointers to itself. 208 // This is useful in cases where you want others to be able to get a weak 209 // pointer to your class. It also has the property that you don't need to 210 // initialize it from your constructor. 211 template <class T> 212 class SupportsWeakPtr { 213 public: SupportsWeakPtr()214 SupportsWeakPtr() {} 215 AsWeakPtr()216 WeakPtr<T> AsWeakPtr() { 217 return WeakPtr<T>(weak_reference_owner_.GetRef(), static_cast<T*>(this)); 218 } 219 220 private: 221 internal::WeakReferenceOwner weak_reference_owner_; 222 DISALLOW_COPY_AND_ASSIGN(SupportsWeakPtr); 223 }; 224 225 // A class may alternatively be composed of a WeakPtrFactory and thereby 226 // control how it exposes weak pointers to itself. This is helpful if you only 227 // need weak pointers within the implementation of a class. This class is also 228 // useful when working with primitive types. For example, you could have a 229 // WeakPtrFactory<bool> that is used to pass around a weak reference to a bool. 230 template <class T> 231 class WeakPtrFactory { 232 public: WeakPtrFactory(T * ptr)233 explicit WeakPtrFactory(T* ptr) : ptr_(ptr) { 234 } 235 GetWeakPtr()236 WeakPtr<T> GetWeakPtr() { 237 return WeakPtr<T>(weak_reference_owner_.GetRef(), ptr_); 238 } 239 240 // Call this method to invalidate all existing weak pointers. InvalidateWeakPtrs()241 void InvalidateWeakPtrs() { 242 weak_reference_owner_.Invalidate(); 243 } 244 245 // Call this method to determine if any weak pointers exist. HasWeakPtrs()246 bool HasWeakPtrs() const { 247 return weak_reference_owner_.HasRefs(); 248 } 249 250 private: 251 internal::WeakReferenceOwner weak_reference_owner_; 252 T* ptr_; 253 DISALLOW_IMPLICIT_CONSTRUCTORS(WeakPtrFactory); 254 }; 255 256 } // namespace base 257 258 #endif // BASE_WEAK_PTR_H_ 259