weak_ptr.h revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
1// Copyright (c) 2012 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// ------------------------ Thread-safety notes ------------------------
49// When you get a WeakPtr (from a WeakPtrFactory or SupportsWeakPtr), if it's
50// the only one pointing to the object, the object become bound to the
51// current thread, as well as this WeakPtr and all later ones get created.
52//
53// You may only dereference the WeakPtr on the thread it binds to. However, it
54// is safe to destroy the WeakPtr object on another thread. Because of this,
55// querying WeakPtrFactory's HasWeakPtrs() method can be racy.
56//
57// On the other hand, the object that supports WeakPtr (extends SupportsWeakPtr)
58// can only be deleted from the thread it binds to, until all WeakPtrs are
59// deleted.
60//
61// Calling SupportsWeakPtr::DetachFromThread() can work around the limitations
62// above and cancel the thread binding of the object and all WeakPtrs pointing
63// to it, but it's not recommended and unsafe.
64//
65// WeakPtrs may be copy-constructed or assigned on threads other than the thread
66// they are bound to. This does not change the thread binding. So these WeakPtrs
67// may only be dereferenced on the thread that the original WeakPtr was bound
68// to.
69
70#ifndef BASE_MEMORY_WEAK_PTR_H_
71#define BASE_MEMORY_WEAK_PTR_H_
72
73#include "base/basictypes.h"
74#include "base/base_export.h"
75#include "base/logging.h"
76#include "base/memory/ref_counted.h"
77#include "base/template_util.h"
78#include "base/threading/thread_checker.h"
79
80namespace base {
81
82template <typename T> class SupportsWeakPtr;
83template <typename T> class WeakPtr;
84
85namespace internal {
86// These classes are part of the WeakPtr implementation.
87// DO NOT USE THESE CLASSES DIRECTLY YOURSELF.
88
89class BASE_EXPORT WeakReference {
90 public:
91  // While Flag is bound to a specific thread, it may be deleted from another
92  // via base::WeakPtr::~WeakPtr().
93  class Flag : public RefCountedThreadSafe<Flag> {
94   public:
95    Flag();
96
97    void Invalidate();
98    bool IsValid() const;
99
100    void DetachFromThread() { thread_checker_.DetachFromThread(); }
101
102   private:
103    friend class base::RefCountedThreadSafe<Flag>;
104
105    ~Flag();
106
107    ThreadChecker thread_checker_;
108    bool is_valid_;
109  };
110
111  WeakReference();
112  explicit WeakReference(const Flag* flag);
113  ~WeakReference();
114
115  bool is_valid() const;
116
117 private:
118  scoped_refptr<const Flag> flag_;
119};
120
121class BASE_EXPORT WeakReferenceOwner {
122 public:
123  WeakReferenceOwner();
124  ~WeakReferenceOwner();
125
126  WeakReference GetRef() const;
127
128  bool HasRefs() const {
129    return flag_.get() && !flag_->HasOneRef();
130  }
131
132  void Invalidate();
133
134  // Indicates that this object will be used on another thread from now on.
135  void DetachFromThread() {
136    if (flag_) flag_->DetachFromThread();
137  }
138
139 private:
140  mutable scoped_refptr<WeakReference::Flag> flag_;
141};
142
143// This class simplifies the implementation of WeakPtr's type conversion
144// constructor by avoiding the need for a public accessor for ref_.  A
145// WeakPtr<T> cannot access the private members of WeakPtr<U>, so this
146// base class gives us a way to access ref_ in a protected fashion.
147class BASE_EXPORT WeakPtrBase {
148 public:
149  WeakPtrBase();
150  ~WeakPtrBase();
151
152 protected:
153  explicit WeakPtrBase(const WeakReference& ref);
154
155  WeakReference ref_;
156};
157
158// This class provides a common implementation of common functions that would
159// otherwise get instantiated separately for each distinct instantiation of
160// SupportsWeakPtr<>.
161class SupportsWeakPtrBase {
162 public:
163  // A safe static downcast of a WeakPtr<Base> to WeakPtr<Derived>. This
164  // conversion will only compile if there is exists a Base which inherits
165  // from SupportsWeakPtr<Base>. See base::AsWeakPtr() below for a helper
166  // function that makes calling this easier.
167  template<typename Derived>
168  static WeakPtr<Derived> StaticAsWeakPtr(Derived* t) {
169    typedef
170        is_convertible<Derived, internal::SupportsWeakPtrBase&> convertible;
171    COMPILE_ASSERT(convertible::value,
172                   AsWeakPtr_argument_inherits_from_SupportsWeakPtr);
173    return AsWeakPtrImpl<Derived>(t, *t);
174  }
175
176 private:
177  // This template function uses type inference to find a Base of Derived
178  // which is an instance of SupportsWeakPtr<Base>. We can then safely
179  // static_cast the Base* to a Derived*.
180  template <typename Derived, typename Base>
181  static WeakPtr<Derived> AsWeakPtrImpl(
182      Derived* t, const SupportsWeakPtr<Base>&) {
183    WeakPtr<Base> ptr = t->Base::AsWeakPtr();
184    return WeakPtr<Derived>(ptr.ref_, static_cast<Derived*>(ptr.ptr_));
185  }
186};
187
188}  // namespace internal
189
190template <typename T> class WeakPtrFactory;
191
192// The WeakPtr class holds a weak reference to |T*|.
193//
194// This class is designed to be used like a normal pointer.  You should always
195// null-test an object of this class before using it or invoking a method that
196// may result in the underlying object being destroyed.
197//
198// EXAMPLE:
199//
200//   class Foo { ... };
201//   WeakPtr<Foo> foo;
202//   if (foo)
203//     foo->method();
204//
205template <typename T>
206class WeakPtr : public internal::WeakPtrBase {
207 public:
208  WeakPtr() : ptr_(NULL) {
209  }
210
211  // Allow conversion from U to T provided U "is a" T. Note that this
212  // is separate from the (implicit) copy constructor.
213  template <typename U>
214  WeakPtr(const WeakPtr<U>& other) : WeakPtrBase(other), ptr_(other.ptr_) {
215  }
216
217  T* get() const { return ref_.is_valid() ? ptr_ : NULL; }
218  operator T*() const { return get(); }
219
220  T& operator*() const {
221    DCHECK(get() != NULL);
222    return *get();
223  }
224  T* operator->() const {
225    DCHECK(get() != NULL);
226    return get();
227  }
228
229  void reset() {
230    ref_ = internal::WeakReference();
231    ptr_ = NULL;
232  }
233
234 private:
235  friend class internal::SupportsWeakPtrBase;
236  template <typename U> friend class WeakPtr;
237  friend class SupportsWeakPtr<T>;
238  friend class WeakPtrFactory<T>;
239
240  WeakPtr(const internal::WeakReference& ref, T* ptr)
241      : WeakPtrBase(ref),
242        ptr_(ptr) {
243  }
244
245  // This pointer is only valid when ref_.is_valid() is true.  Otherwise, its
246  // value is undefined (as opposed to NULL).
247  T* ptr_;
248};
249
250// A class may extend from SupportsWeakPtr to expose weak pointers to itself.
251// This is useful in cases where you want others to be able to get a weak
252// pointer to your class.  It also has the property that you don't need to
253// initialize it from your constructor.
254template <class T>
255class SupportsWeakPtr : public internal::SupportsWeakPtrBase {
256 public:
257  SupportsWeakPtr() {}
258
259  WeakPtr<T> AsWeakPtr() {
260    return WeakPtr<T>(weak_reference_owner_.GetRef(), static_cast<T*>(this));
261  }
262
263  // Indicates that this object will be used on another thread from now on.
264  void DetachFromThread() {
265    weak_reference_owner_.DetachFromThread();
266  }
267
268 protected:
269  ~SupportsWeakPtr() {}
270
271 private:
272  internal::WeakReferenceOwner weak_reference_owner_;
273  DISALLOW_COPY_AND_ASSIGN(SupportsWeakPtr);
274};
275
276// Helper function that uses type deduction to safely return a WeakPtr<Derived>
277// when Derived doesn't directly extend SupportsWeakPtr<Derived>, instead it
278// extends a Base that extends SupportsWeakPtr<Base>.
279//
280// EXAMPLE:
281//   class Base : public base::SupportsWeakPtr<Producer> {};
282//   class Derived : public Base {};
283//
284//   Derived derived;
285//   base::WeakPtr<Derived> ptr = base::AsWeakPtr(&derived);
286//
287// Note that the following doesn't work (invalid type conversion) since
288// Derived::AsWeakPtr() is WeakPtr<Base> SupportsWeakPtr<Base>::AsWeakPtr(),
289// and there's no way to safely cast WeakPtr<Base> to WeakPtr<Derived> at
290// the caller.
291//
292//   base::WeakPtr<Derived> ptr = derived.AsWeakPtr();  // Fails.
293
294template <typename Derived>
295WeakPtr<Derived> AsWeakPtr(Derived* t) {
296  return internal::SupportsWeakPtrBase::StaticAsWeakPtr<Derived>(t);
297}
298
299// A class may alternatively be composed of a WeakPtrFactory and thereby
300// control how it exposes weak pointers to itself.  This is helpful if you only
301// need weak pointers within the implementation of a class.  This class is also
302// useful when working with primitive types.  For example, you could have a
303// WeakPtrFactory<bool> that is used to pass around a weak reference to a bool.
304template <class T>
305class WeakPtrFactory {
306 public:
307  explicit WeakPtrFactory(T* ptr) : ptr_(ptr) {
308  }
309
310  ~WeakPtrFactory() {
311    ptr_ = NULL;
312  }
313
314  WeakPtr<T> GetWeakPtr() {
315    DCHECK(ptr_);
316    return WeakPtr<T>(weak_reference_owner_.GetRef(), ptr_);
317  }
318
319  // Call this method to invalidate all existing weak pointers.
320  void InvalidateWeakPtrs() {
321    DCHECK(ptr_);
322    weak_reference_owner_.Invalidate();
323  }
324
325  // Call this method to determine if any weak pointers exist.
326  bool HasWeakPtrs() const {
327    DCHECK(ptr_);
328    return weak_reference_owner_.HasRefs();
329  }
330
331  // Indicates that this object will be used on another thread from now on.
332  void DetachFromThread() {
333    DCHECK(ptr_);
334    weak_reference_owner_.DetachFromThread();
335  }
336
337 private:
338  internal::WeakReferenceOwner weak_reference_owner_;
339  T* ptr_;
340  DISALLOW_IMPLICIT_CONSTRUCTORS(WeakPtrFactory);
341};
342
343}  // namespace base
344
345#endif  // BASE_MEMORY_WEAK_PTR_H_
346