1 // Copyright (c) 2011 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_MEMORY_WEAK_PTR_H_ 52 #define BASE_MEMORY_WEAK_PTR_H_ 53 #pragma once 54 55 #include "base/base_api.h" 56 #include "base/logging.h" 57 #include "base/memory/ref_counted.h" 58 #include "base/threading/thread_checker.h" 59 60 namespace base { 61 62 namespace internal { 63 // These classes are part of the WeakPtr implementation. 64 // DO NOT USE THESE CLASSES DIRECTLY YOURSELF. 65 66 class BASE_API WeakReference { 67 public: 68 // While Flag is bound to a specific thread, it may be deleted from another 69 // via base::WeakPtr::~WeakPtr(). 70 class Flag : public RefCountedThreadSafe<Flag> { 71 public: 72 explicit Flag(Flag** handle); 73 74 void Invalidate(); 75 bool IsValid() const; 76 DetachFromThread()77 void DetachFromThread() { thread_checker_.DetachFromThread(); } 78 79 private: 80 friend class base::RefCountedThreadSafe<Flag>; 81 82 ~Flag(); 83 84 ThreadChecker thread_checker_; 85 Flag** handle_; 86 }; 87 88 WeakReference(); 89 WeakReference(Flag* flag); 90 ~WeakReference(); 91 92 bool is_valid() const; 93 94 private: 95 scoped_refptr<Flag> flag_; 96 }; 97 98 class BASE_API WeakReferenceOwner { 99 public: 100 WeakReferenceOwner(); 101 ~WeakReferenceOwner(); 102 103 WeakReference GetRef() const; 104 HasRefs()105 bool HasRefs() const { 106 return flag_ != NULL; 107 } 108 109 void Invalidate(); 110 111 // Indicates that this object will be used on another thread from now on. DetachFromThread()112 void DetachFromThread() { 113 if (flag_) flag_->DetachFromThread(); 114 } 115 116 private: 117 mutable WeakReference::Flag* flag_; 118 }; 119 120 // This class simplifies the implementation of WeakPtr's type conversion 121 // constructor by avoiding the need for a public accessor for ref_. A 122 // WeakPtr<T> cannot access the private members of WeakPtr<U>, so this 123 // base class gives us a way to access ref_ in a protected fashion. 124 class BASE_API WeakPtrBase { 125 public: 126 WeakPtrBase(); 127 ~WeakPtrBase(); 128 129 protected: 130 WeakPtrBase(const WeakReference& ref); 131 132 WeakReference ref_; 133 }; 134 135 } // namespace internal 136 137 template <typename T> class SupportsWeakPtr; 138 template <typename T> class WeakPtrFactory; 139 140 // The WeakPtr class holds a weak reference to |T*|. 141 // 142 // This class is designed to be used like a normal pointer. You should always 143 // null-test an object of this class before using it or invoking a method that 144 // may result in the underlying object being destroyed. 145 // 146 // EXAMPLE: 147 // 148 // class Foo { ... }; 149 // WeakPtr<Foo> foo; 150 // if (foo) 151 // foo->method(); 152 // 153 template <typename T> 154 class WeakPtr : public internal::WeakPtrBase { 155 public: WeakPtr()156 WeakPtr() : ptr_(NULL) { 157 } 158 159 // Allow conversion from U to T provided U "is a" T. 160 template <typename U> WeakPtr(const WeakPtr<U> & other)161 WeakPtr(const WeakPtr<U>& other) : WeakPtrBase(other), ptr_(other.get()) { 162 } 163 get()164 T* get() const { return ref_.is_valid() ? ptr_ : NULL; } 165 operator T*() const { return get(); } 166 167 T* operator*() const { 168 DCHECK(get() != NULL); 169 return *get(); 170 } 171 T* operator->() const { 172 DCHECK(get() != NULL); 173 return get(); 174 } 175 reset()176 void reset() { 177 ref_ = internal::WeakReference(); 178 ptr_ = NULL; 179 } 180 181 private: 182 friend class SupportsWeakPtr<T>; 183 friend class WeakPtrFactory<T>; 184 WeakPtr(const internal::WeakReference & ref,T * ptr)185 WeakPtr(const internal::WeakReference& ref, T* ptr) 186 : WeakPtrBase(ref), ptr_(ptr) { 187 } 188 189 // This pointer is only valid when ref_.is_valid() is true. Otherwise, its 190 // value is undefined (as opposed to NULL). 191 T* ptr_; 192 }; 193 194 // A class may extend from SupportsWeakPtr to expose weak pointers to itself. 195 // This is useful in cases where you want others to be able to get a weak 196 // pointer to your class. It also has the property that you don't need to 197 // initialize it from your constructor. 198 template <class T> 199 class SupportsWeakPtr { 200 public: SupportsWeakPtr()201 SupportsWeakPtr() {} 202 AsWeakPtr()203 WeakPtr<T> AsWeakPtr() { 204 return WeakPtr<T>(weak_reference_owner_.GetRef(), static_cast<T*>(this)); 205 } 206 207 // Indicates that this object will be used on another thread from now on. DetachFromThread()208 void DetachFromThread() { 209 weak_reference_owner_.DetachFromThread(); 210 } 211 212 private: 213 internal::WeakReferenceOwner weak_reference_owner_; 214 DISALLOW_COPY_AND_ASSIGN(SupportsWeakPtr); 215 }; 216 217 // A class may alternatively be composed of a WeakPtrFactory and thereby 218 // control how it exposes weak pointers to itself. This is helpful if you only 219 // need weak pointers within the implementation of a class. This class is also 220 // useful when working with primitive types. For example, you could have a 221 // WeakPtrFactory<bool> that is used to pass around a weak reference to a bool. 222 template <class T> 223 class WeakPtrFactory { 224 public: WeakPtrFactory(T * ptr)225 explicit WeakPtrFactory(T* ptr) : ptr_(ptr) { 226 } 227 GetWeakPtr()228 WeakPtr<T> GetWeakPtr() { 229 return WeakPtr<T>(weak_reference_owner_.GetRef(), ptr_); 230 } 231 232 // Call this method to invalidate all existing weak pointers. InvalidateWeakPtrs()233 void InvalidateWeakPtrs() { 234 weak_reference_owner_.Invalidate(); 235 } 236 237 // Call this method to determine if any weak pointers exist. HasWeakPtrs()238 bool HasWeakPtrs() const { 239 return weak_reference_owner_.HasRefs(); 240 } 241 242 // Indicates that this object will be used on another thread from now on. DetachFromThread()243 void DetachFromThread() { 244 weak_reference_owner_.DetachFromThread(); 245 } 246 247 private: 248 internal::WeakReferenceOwner weak_reference_owner_; 249 T* ptr_; 250 DISALLOW_IMPLICIT_CONSTRUCTORS(WeakPtrFactory); 251 }; 252 253 } // namespace base 254 255 #endif // BASE_MEMORY_WEAK_PTR_H_ 256