OLD | NEW |
(Empty) | |
| 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 { |
| 20 // public: |
| 21 // void SpawnWorker() { Worker::StartNew(GetWeakPtr()); } |
| 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 void EnsureInitialized() { |
| 67 // Lazy initialization helps faciliate the NonThreadSafe debug checks. |
| 68 if (!flag_) { |
| 69 flag_ = new Flag(); |
| 70 flag_->data = true; |
| 71 } |
| 72 } |
| 73 |
| 74 void Invalidate() { |
| 75 if (flag_) |
| 76 flag_->data = false; |
| 77 } |
| 78 |
| 79 bool is_valid() const { return flag_ && flag_->data; } |
| 80 |
| 81 private: |
| 82 // A reference counted boolean that is true when the weak reference is valid |
| 83 // and false otherwise. |
| 84 class Flag : public RefCountedData<bool>, public NonThreadSafe { |
| 85 }; |
| 86 |
| 87 scoped_refptr<Flag> flag_; |
| 88 }; |
| 89 |
| 90 class WeakReferenceOwner { |
| 91 public: |
| 92 ~WeakReferenceOwner() { |
| 93 ref_.Invalidate(); |
| 94 } |
| 95 |
| 96 const WeakReference& GetRef() const { |
| 97 ref_.EnsureInitialized(); |
| 98 return ref_; |
| 99 } |
| 100 |
| 101 void Invalidate() { ref_.Invalidate(); } |
| 102 |
| 103 private: |
| 104 mutable WeakReference ref_; |
| 105 }; |
| 106 |
| 107 // This class simplifies the implementation of WeakPtr's type conversion |
| 108 // constructor by avoiding the need for a public accessor for ref_. A |
| 109 // WeakPtr<T> cannot access the private members of WeakPtr<U>, so this |
| 110 // base class gives us a way to access ref_ in a protected fashion. |
| 111 class WeakPtrBase { |
| 112 public: |
| 113 WeakPtrBase() { |
| 114 } |
| 115 |
| 116 protected: |
| 117 WeakPtrBase(const WeakReference& ref) : ref_(ref) { |
| 118 } |
| 119 |
| 120 WeakReference ref_; |
| 121 }; |
| 122 |
| 123 } // namespace internal |
| 124 |
| 125 template <typename T> class SupportsWeakPtr; |
| 126 template <typename T> class WeakPtrFactory; |
| 127 |
| 128 // The WeakPtr class holds a weak reference to |T*|. |
| 129 // |
| 130 // This class is designed to be used like a normal pointer. You should always |
| 131 // null-test an object of this class before using it or invoking a method that |
| 132 // may result in the underlying object being destroyed. |
| 133 // |
| 134 // EXAMPLE: |
| 135 // |
| 136 // class Foo { ... }; |
| 137 // WeakPtr<Foo> foo; |
| 138 // if (foo) |
| 139 // foo->method(); |
| 140 // |
| 141 template <typename T> |
| 142 class WeakPtr : public internal::WeakPtrBase { |
| 143 public: |
| 144 WeakPtr() : ptr_(NULL) { |
| 145 } |
| 146 |
| 147 // Allow conversion from U to T provided U "is a" T. |
| 148 template <typename U> |
| 149 WeakPtr(const WeakPtr<U>& other) : WeakPtrBase(other), ptr_(other.get()) { |
| 150 } |
| 151 |
| 152 T* get() const { return ref_.is_valid() ? ptr_ : NULL; } |
| 153 operator T*() const { return get(); } |
| 154 |
| 155 T* operator*() const { |
| 156 DCHECK(get() != NULL); |
| 157 return *get(); |
| 158 } |
| 159 T* operator->() const { |
| 160 DCHECK(get() != NULL); |
| 161 return get(); |
| 162 } |
| 163 |
| 164 private: |
| 165 friend class SupportsWeakPtr<T>; |
| 166 friend class WeakPtrFactory<T>; |
| 167 |
| 168 WeakPtr(const internal::WeakReference& ref, T* ptr) |
| 169 : WeakPtrBase(ref), ptr_(ptr) { |
| 170 } |
| 171 |
| 172 // This pointer is only valid when ref_.is_valid() is true. Otherwise, its |
| 173 // value is undefined (as opposed to NULL). |
| 174 T* ptr_; |
| 175 }; |
| 176 |
| 177 // A class may extend from SupportsWeakPtr to expose weak pointers to itself. |
| 178 // This is useful in cases where you want others to be able to get a weak |
| 179 // pointer to your class. It also has the property that you don't need to |
| 180 // initialize it from your constructor. |
| 181 template <class T> |
| 182 class SupportsWeakPtr { |
| 183 public: |
| 184 SupportsWeakPtr() {} |
| 185 |
| 186 WeakPtr<T> AsWeakPtr() { |
| 187 return WeakPtr<T>(weak_reference_owner_.GetRef(), static_cast<T*>(this)); |
| 188 } |
| 189 |
| 190 private: |
| 191 internal::WeakReferenceOwner weak_reference_owner_; |
| 192 DISALLOW_COPY_AND_ASSIGN(SupportsWeakPtr); |
| 193 }; |
| 194 |
| 195 // A class may alternatively be composed of a WeakPtrFactory and thereby |
| 196 // control how it exposes weak pointers to itself. This is helpful if you only |
| 197 // need weak pointers within the implementation of a class. This class is also |
| 198 // useful when working with primitive types. For example, you could have a |
| 199 // WeakPtrFactory<bool> that is used to pass around a weak reference to a bool. |
| 200 template <class T> |
| 201 class WeakPtrFactory { |
| 202 public: |
| 203 explicit WeakPtrFactory(T* ptr) : ptr_(ptr) { |
| 204 } |
| 205 |
| 206 WeakPtr<T> GetWeakPtr() { |
| 207 return WeakPtr<T>(weak_reference_owner_.GetRef(), ptr_); |
| 208 } |
| 209 |
| 210 // Call this method to invalidate all existing weak pointers. |
| 211 void InvalidateWeakPtrs() { weak_reference_owner_.Invalidate(); } |
| 212 |
| 213 private: |
| 214 internal::WeakReferenceOwner weak_reference_owner_; |
| 215 T* ptr_; |
| 216 DISALLOW_IMPLICIT_CONSTRUCTORS(WeakPtrFactory); |
| 217 }; |
| 218 |
| 219 } // namespace base |
| 220 |
| 221 #endif // BASE_WEAK_PTR_H_ |
OLD | NEW |