• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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