Wed, 31 Dec 2014 07:16:47 +0100
Revert simplistic fix pending revisit of Mozilla integration attempt.
michael@0 | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
michael@0 | 2 | // Use of this source code is governed by a BSD-style license that can be |
michael@0 | 3 | // found in the LICENSE file. |
michael@0 | 4 | |
michael@0 | 5 | // Weak pointers are pointers to an object that do not affect its lifetime, |
michael@0 | 6 | // and which may be invalidated (i.e. reset to NULL) by the object, or its |
michael@0 | 7 | // owner, at any time, most commonly when the object is about to be deleted. |
michael@0 | 8 | |
michael@0 | 9 | // Weak pointers are useful when an object needs to be accessed safely by one |
michael@0 | 10 | // or more objects other than its owner, and those callers can cope with the |
michael@0 | 11 | // object vanishing and e.g. tasks posted to it being silently dropped. |
michael@0 | 12 | // Reference-counting such an object would complicate the ownership graph and |
michael@0 | 13 | // make it harder to reason about the object's lifetime. |
michael@0 | 14 | |
michael@0 | 15 | // EXAMPLE: |
michael@0 | 16 | // |
michael@0 | 17 | // class Controller { |
michael@0 | 18 | // public: |
michael@0 | 19 | // void SpawnWorker() { Worker::StartNew(weak_factory_.GetWeakPtr()); } |
michael@0 | 20 | // void WorkComplete(const Result& result) { ... } |
michael@0 | 21 | // private: |
michael@0 | 22 | // // Member variables should appear before the WeakPtrFactory, to ensure |
michael@0 | 23 | // // that any WeakPtrs to Controller are invalidated before its members |
michael@0 | 24 | // // variable's destructors are executed, rendering them invalid. |
michael@0 | 25 | // WeakPtrFactory<Controller> weak_factory_; |
michael@0 | 26 | // }; |
michael@0 | 27 | // |
michael@0 | 28 | // class Worker { |
michael@0 | 29 | // public: |
michael@0 | 30 | // static void StartNew(const WeakPtr<Controller>& controller) { |
michael@0 | 31 | // Worker* worker = new Worker(controller); |
michael@0 | 32 | // // Kick off asynchronous processing... |
michael@0 | 33 | // } |
michael@0 | 34 | // private: |
michael@0 | 35 | // Worker(const WeakPtr<Controller>& controller) |
michael@0 | 36 | // : controller_(controller) {} |
michael@0 | 37 | // void DidCompleteAsynchronousProcessing(const Result& result) { |
michael@0 | 38 | // if (controller_) |
michael@0 | 39 | // controller_->WorkComplete(result); |
michael@0 | 40 | // } |
michael@0 | 41 | // WeakPtr<Controller> controller_; |
michael@0 | 42 | // }; |
michael@0 | 43 | // |
michael@0 | 44 | // With this implementation a caller may use SpawnWorker() to dispatch multiple |
michael@0 | 45 | // Workers and subsequently delete the Controller, without waiting for all |
michael@0 | 46 | // Workers to have completed. |
michael@0 | 47 | |
michael@0 | 48 | // ------------------------- IMPORTANT: Thread-safety ------------------------- |
michael@0 | 49 | |
michael@0 | 50 | // Weak pointers may be passed safely between threads, but must always be |
michael@0 | 51 | // dereferenced and invalidated on the same thread otherwise checking the |
michael@0 | 52 | // pointer would be racey. |
michael@0 | 53 | // |
michael@0 | 54 | // To ensure correct use, the first time a WeakPtr issued by a WeakPtrFactory |
michael@0 | 55 | // is dereferenced, the factory and its WeakPtrs become bound to the calling |
michael@0 | 56 | // thread, and cannot be dereferenced or invalidated on any other thread. Bound |
michael@0 | 57 | // WeakPtrs can still be handed off to other threads, e.g. to use to post tasks |
michael@0 | 58 | // back to object on the bound thread. |
michael@0 | 59 | // |
michael@0 | 60 | // Invalidating the factory's WeakPtrs un-binds it from the thread, allowing it |
michael@0 | 61 | // to be passed for a different thread to use or delete it. |
michael@0 | 62 | |
michael@0 | 63 | #ifndef BASE_MEMORY_WEAK_PTR_H_ |
michael@0 | 64 | #define BASE_MEMORY_WEAK_PTR_H_ |
michael@0 | 65 | |
michael@0 | 66 | #include "base/basictypes.h" |
michael@0 | 67 | #include "base/base_export.h" |
michael@0 | 68 | #include "base/logging.h" |
michael@0 | 69 | #include "base/memory/ref_counted.h" |
michael@0 | 70 | #include "base/sequence_checker.h" |
michael@0 | 71 | #include "base/template_util.h" |
michael@0 | 72 | |
michael@0 | 73 | namespace base { |
michael@0 | 74 | |
michael@0 | 75 | template <typename T> class SupportsWeakPtr; |
michael@0 | 76 | template <typename T> class WeakPtr; |
michael@0 | 77 | |
michael@0 | 78 | namespace internal { |
michael@0 | 79 | // These classes are part of the WeakPtr implementation. |
michael@0 | 80 | // DO NOT USE THESE CLASSES DIRECTLY YOURSELF. |
michael@0 | 81 | |
michael@0 | 82 | class BASE_EXPORT WeakReference { |
michael@0 | 83 | public: |
michael@0 | 84 | // Although Flag is bound to a specific thread, it may be deleted from another |
michael@0 | 85 | // via base::WeakPtr::~WeakPtr(). |
michael@0 | 86 | class Flag : public RefCountedThreadSafe<Flag> { |
michael@0 | 87 | public: |
michael@0 | 88 | Flag(); |
michael@0 | 89 | |
michael@0 | 90 | void Invalidate(); |
michael@0 | 91 | bool IsValid() const; |
michael@0 | 92 | |
michael@0 | 93 | private: |
michael@0 | 94 | friend class base::RefCountedThreadSafe<Flag>; |
michael@0 | 95 | |
michael@0 | 96 | ~Flag(); |
michael@0 | 97 | |
michael@0 | 98 | SequenceChecker sequence_checker_; |
michael@0 | 99 | bool is_valid_; |
michael@0 | 100 | }; |
michael@0 | 101 | |
michael@0 | 102 | WeakReference(); |
michael@0 | 103 | explicit WeakReference(const Flag* flag); |
michael@0 | 104 | ~WeakReference(); |
michael@0 | 105 | |
michael@0 | 106 | bool is_valid() const; |
michael@0 | 107 | |
michael@0 | 108 | private: |
michael@0 | 109 | scoped_refptr<const Flag> flag_; |
michael@0 | 110 | }; |
michael@0 | 111 | |
michael@0 | 112 | class BASE_EXPORT WeakReferenceOwner { |
michael@0 | 113 | public: |
michael@0 | 114 | WeakReferenceOwner(); |
michael@0 | 115 | ~WeakReferenceOwner(); |
michael@0 | 116 | |
michael@0 | 117 | WeakReference GetRef() const; |
michael@0 | 118 | |
michael@0 | 119 | bool HasRefs() const { |
michael@0 | 120 | return flag_.get() && !flag_->HasOneRef(); |
michael@0 | 121 | } |
michael@0 | 122 | |
michael@0 | 123 | void Invalidate(); |
michael@0 | 124 | |
michael@0 | 125 | private: |
michael@0 | 126 | mutable scoped_refptr<WeakReference::Flag> flag_; |
michael@0 | 127 | }; |
michael@0 | 128 | |
michael@0 | 129 | // This class simplifies the implementation of WeakPtr's type conversion |
michael@0 | 130 | // constructor by avoiding the need for a public accessor for ref_. A |
michael@0 | 131 | // WeakPtr<T> cannot access the private members of WeakPtr<U>, so this |
michael@0 | 132 | // base class gives us a way to access ref_ in a protected fashion. |
michael@0 | 133 | class BASE_EXPORT WeakPtrBase { |
michael@0 | 134 | public: |
michael@0 | 135 | WeakPtrBase(); |
michael@0 | 136 | ~WeakPtrBase(); |
michael@0 | 137 | |
michael@0 | 138 | protected: |
michael@0 | 139 | explicit WeakPtrBase(const WeakReference& ref); |
michael@0 | 140 | |
michael@0 | 141 | WeakReference ref_; |
michael@0 | 142 | }; |
michael@0 | 143 | |
michael@0 | 144 | // This class provides a common implementation of common functions that would |
michael@0 | 145 | // otherwise get instantiated separately for each distinct instantiation of |
michael@0 | 146 | // SupportsWeakPtr<>. |
michael@0 | 147 | class SupportsWeakPtrBase { |
michael@0 | 148 | public: |
michael@0 | 149 | // A safe static downcast of a WeakPtr<Base> to WeakPtr<Derived>. This |
michael@0 | 150 | // conversion will only compile if there is exists a Base which inherits |
michael@0 | 151 | // from SupportsWeakPtr<Base>. See base::AsWeakPtr() below for a helper |
michael@0 | 152 | // function that makes calling this easier. |
michael@0 | 153 | template<typename Derived> |
michael@0 | 154 | static WeakPtr<Derived> StaticAsWeakPtr(Derived* t) { |
michael@0 | 155 | typedef |
michael@0 | 156 | is_convertible<Derived, internal::SupportsWeakPtrBase&> convertible; |
michael@0 | 157 | COMPILE_ASSERT(convertible::value, |
michael@0 | 158 | AsWeakPtr_argument_inherits_from_SupportsWeakPtr); |
michael@0 | 159 | return AsWeakPtrImpl<Derived>(t, *t); |
michael@0 | 160 | } |
michael@0 | 161 | |
michael@0 | 162 | private: |
michael@0 | 163 | // This template function uses type inference to find a Base of Derived |
michael@0 | 164 | // which is an instance of SupportsWeakPtr<Base>. We can then safely |
michael@0 | 165 | // static_cast the Base* to a Derived*. |
michael@0 | 166 | template <typename Derived, typename Base> |
michael@0 | 167 | static WeakPtr<Derived> AsWeakPtrImpl( |
michael@0 | 168 | Derived* t, const SupportsWeakPtr<Base>&) { |
michael@0 | 169 | WeakPtr<Base> ptr = t->Base::AsWeakPtr(); |
michael@0 | 170 | return WeakPtr<Derived>(ptr.ref_, static_cast<Derived*>(ptr.ptr_)); |
michael@0 | 171 | } |
michael@0 | 172 | }; |
michael@0 | 173 | |
michael@0 | 174 | } // namespace internal |
michael@0 | 175 | |
michael@0 | 176 | template <typename T> class WeakPtrFactory; |
michael@0 | 177 | |
michael@0 | 178 | // The WeakPtr class holds a weak reference to |T*|. |
michael@0 | 179 | // |
michael@0 | 180 | // This class is designed to be used like a normal pointer. You should always |
michael@0 | 181 | // null-test an object of this class before using it or invoking a method that |
michael@0 | 182 | // may result in the underlying object being destroyed. |
michael@0 | 183 | // |
michael@0 | 184 | // EXAMPLE: |
michael@0 | 185 | // |
michael@0 | 186 | // class Foo { ... }; |
michael@0 | 187 | // WeakPtr<Foo> foo; |
michael@0 | 188 | // if (foo) |
michael@0 | 189 | // foo->method(); |
michael@0 | 190 | // |
michael@0 | 191 | template <typename T> |
michael@0 | 192 | class WeakPtr : public internal::WeakPtrBase { |
michael@0 | 193 | public: |
michael@0 | 194 | WeakPtr() : ptr_(NULL) { |
michael@0 | 195 | } |
michael@0 | 196 | |
michael@0 | 197 | // Allow conversion from U to T provided U "is a" T. Note that this |
michael@0 | 198 | // is separate from the (implicit) copy constructor. |
michael@0 | 199 | template <typename U> |
michael@0 | 200 | WeakPtr(const WeakPtr<U>& other) : WeakPtrBase(other), ptr_(other.ptr_) { |
michael@0 | 201 | } |
michael@0 | 202 | |
michael@0 | 203 | T* get() const { return ref_.is_valid() ? ptr_ : NULL; } |
michael@0 | 204 | |
michael@0 | 205 | T& operator*() const { |
michael@0 | 206 | DCHECK(get() != NULL); |
michael@0 | 207 | return *get(); |
michael@0 | 208 | } |
michael@0 | 209 | T* operator->() const { |
michael@0 | 210 | DCHECK(get() != NULL); |
michael@0 | 211 | return get(); |
michael@0 | 212 | } |
michael@0 | 213 | |
michael@0 | 214 | // Allow WeakPtr<element_type> to be used in boolean expressions, but not |
michael@0 | 215 | // implicitly convertible to a real bool (which is dangerous). |
michael@0 | 216 | // |
michael@0 | 217 | // Note that this trick is only safe when the == and != operators |
michael@0 | 218 | // are declared explicitly, as otherwise "weak_ptr1 == weak_ptr2" |
michael@0 | 219 | // will compile but do the wrong thing (i.e., convert to Testable |
michael@0 | 220 | // and then do the comparison). |
michael@0 | 221 | private: |
michael@0 | 222 | typedef T* WeakPtr::*Testable; |
michael@0 | 223 | |
michael@0 | 224 | public: |
michael@0 | 225 | operator Testable() const { return get() ? &WeakPtr::ptr_ : NULL; } |
michael@0 | 226 | |
michael@0 | 227 | void reset() { |
michael@0 | 228 | ref_ = internal::WeakReference(); |
michael@0 | 229 | ptr_ = NULL; |
michael@0 | 230 | } |
michael@0 | 231 | |
michael@0 | 232 | private: |
michael@0 | 233 | // Explicitly declare comparison operators as required by the bool |
michael@0 | 234 | // trick, but keep them private. |
michael@0 | 235 | template <class U> bool operator==(WeakPtr<U> const&) const; |
michael@0 | 236 | template <class U> bool operator!=(WeakPtr<U> const&) const; |
michael@0 | 237 | |
michael@0 | 238 | friend class internal::SupportsWeakPtrBase; |
michael@0 | 239 | template <typename U> friend class WeakPtr; |
michael@0 | 240 | friend class SupportsWeakPtr<T>; |
michael@0 | 241 | friend class WeakPtrFactory<T>; |
michael@0 | 242 | |
michael@0 | 243 | WeakPtr(const internal::WeakReference& ref, T* ptr) |
michael@0 | 244 | : WeakPtrBase(ref), |
michael@0 | 245 | ptr_(ptr) { |
michael@0 | 246 | } |
michael@0 | 247 | |
michael@0 | 248 | // This pointer is only valid when ref_.is_valid() is true. Otherwise, its |
michael@0 | 249 | // value is undefined (as opposed to NULL). |
michael@0 | 250 | T* ptr_; |
michael@0 | 251 | }; |
michael@0 | 252 | |
michael@0 | 253 | // A class may be composed of a WeakPtrFactory and thereby |
michael@0 | 254 | // control how it exposes weak pointers to itself. This is helpful if you only |
michael@0 | 255 | // need weak pointers within the implementation of a class. This class is also |
michael@0 | 256 | // useful when working with primitive types. For example, you could have a |
michael@0 | 257 | // WeakPtrFactory<bool> that is used to pass around a weak reference to a bool. |
michael@0 | 258 | template <class T> |
michael@0 | 259 | class WeakPtrFactory { |
michael@0 | 260 | public: |
michael@0 | 261 | explicit WeakPtrFactory(T* ptr) : ptr_(ptr) { |
michael@0 | 262 | } |
michael@0 | 263 | |
michael@0 | 264 | ~WeakPtrFactory() { |
michael@0 | 265 | ptr_ = NULL; |
michael@0 | 266 | } |
michael@0 | 267 | |
michael@0 | 268 | WeakPtr<T> GetWeakPtr() { |
michael@0 | 269 | DCHECK(ptr_); |
michael@0 | 270 | return WeakPtr<T>(weak_reference_owner_.GetRef(), ptr_); |
michael@0 | 271 | } |
michael@0 | 272 | |
michael@0 | 273 | // Call this method to invalidate all existing weak pointers. |
michael@0 | 274 | void InvalidateWeakPtrs() { |
michael@0 | 275 | DCHECK(ptr_); |
michael@0 | 276 | weak_reference_owner_.Invalidate(); |
michael@0 | 277 | } |
michael@0 | 278 | |
michael@0 | 279 | // Call this method to determine if any weak pointers exist. |
michael@0 | 280 | bool HasWeakPtrs() const { |
michael@0 | 281 | DCHECK(ptr_); |
michael@0 | 282 | return weak_reference_owner_.HasRefs(); |
michael@0 | 283 | } |
michael@0 | 284 | |
michael@0 | 285 | private: |
michael@0 | 286 | internal::WeakReferenceOwner weak_reference_owner_; |
michael@0 | 287 | T* ptr_; |
michael@0 | 288 | DISALLOW_IMPLICIT_CONSTRUCTORS(WeakPtrFactory); |
michael@0 | 289 | }; |
michael@0 | 290 | |
michael@0 | 291 | // A class may extend from SupportsWeakPtr to let others take weak pointers to |
michael@0 | 292 | // it. This avoids the class itself implementing boilerplate to dispense weak |
michael@0 | 293 | // pointers. However, since SupportsWeakPtr's destructor won't invalidate |
michael@0 | 294 | // weak pointers to the class until after the derived class' members have been |
michael@0 | 295 | // destroyed, its use can lead to subtle use-after-destroy issues. |
michael@0 | 296 | template <class T> |
michael@0 | 297 | class SupportsWeakPtr : public internal::SupportsWeakPtrBase { |
michael@0 | 298 | public: |
michael@0 | 299 | SupportsWeakPtr() {} |
michael@0 | 300 | |
michael@0 | 301 | WeakPtr<T> AsWeakPtr() { |
michael@0 | 302 | return WeakPtr<T>(weak_reference_owner_.GetRef(), static_cast<T*>(this)); |
michael@0 | 303 | } |
michael@0 | 304 | |
michael@0 | 305 | protected: |
michael@0 | 306 | ~SupportsWeakPtr() {} |
michael@0 | 307 | |
michael@0 | 308 | private: |
michael@0 | 309 | internal::WeakReferenceOwner weak_reference_owner_; |
michael@0 | 310 | DISALLOW_COPY_AND_ASSIGN(SupportsWeakPtr); |
michael@0 | 311 | }; |
michael@0 | 312 | |
michael@0 | 313 | // Helper function that uses type deduction to safely return a WeakPtr<Derived> |
michael@0 | 314 | // when Derived doesn't directly extend SupportsWeakPtr<Derived>, instead it |
michael@0 | 315 | // extends a Base that extends SupportsWeakPtr<Base>. |
michael@0 | 316 | // |
michael@0 | 317 | // EXAMPLE: |
michael@0 | 318 | // class Base : public base::SupportsWeakPtr<Producer> {}; |
michael@0 | 319 | // class Derived : public Base {}; |
michael@0 | 320 | // |
michael@0 | 321 | // Derived derived; |
michael@0 | 322 | // base::WeakPtr<Derived> ptr = base::AsWeakPtr(&derived); |
michael@0 | 323 | // |
michael@0 | 324 | // Note that the following doesn't work (invalid type conversion) since |
michael@0 | 325 | // Derived::AsWeakPtr() is WeakPtr<Base> SupportsWeakPtr<Base>::AsWeakPtr(), |
michael@0 | 326 | // and there's no way to safely cast WeakPtr<Base> to WeakPtr<Derived> at |
michael@0 | 327 | // the caller. |
michael@0 | 328 | // |
michael@0 | 329 | // base::WeakPtr<Derived> ptr = derived.AsWeakPtr(); // Fails. |
michael@0 | 330 | |
michael@0 | 331 | template <typename Derived> |
michael@0 | 332 | WeakPtr<Derived> AsWeakPtr(Derived* t) { |
michael@0 | 333 | return internal::SupportsWeakPtrBase::StaticAsWeakPtr<Derived>(t); |
michael@0 | 334 | } |
michael@0 | 335 | |
michael@0 | 336 | } // namespace base |
michael@0 | 337 | |
michael@0 | 338 | #endif // BASE_MEMORY_WEAK_PTR_H_ |