Home | History | Annotate | Download | only in base
      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:
     68     Flag(Flag** handle) : handle_(handle) {
     69     }
     70 
     71     ~Flag() {
     72       if (handle_)
     73         *handle_ = NULL;
     74     }
     75 
     76     void AddRef() {
     77       DCHECK(CalledOnValidThread());
     78       RefCounted<Flag>::AddRef();
     79     }
     80 
     81     void Release() {
     82       DCHECK(CalledOnValidThread());
     83       RefCounted<Flag>::Release();
     84     }
     85 
     86     void Invalidate() { handle_ = NULL; }
     87     bool is_valid() const { return handle_ != NULL; }
     88 
     89    private:
     90     Flag** handle_;
     91   };
     92 
     93   WeakReference() {}
     94   WeakReference(Flag* flag) : flag_(flag) {}
     95 
     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:
    104   WeakReferenceOwner() : flag_(NULL) {
    105   }
    106 
    107   ~WeakReferenceOwner() {
    108     Invalidate();
    109   }
    110 
    111   WeakReference GetRef() const {
    112     if (!flag_)
    113       flag_ = new WeakReference::Flag(&flag_);
    114     return WeakReference(flag_);
    115   }
    116 
    117   bool HasRefs() const {
    118     return flag_ != NULL;
    119   }
    120 
    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:
    138   WeakPtrBase() {
    139   }
    140 
    141  protected:
    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:
    169   WeakPtr() : ptr_(NULL) {
    170   }
    171 
    172   // Allow conversion from U to T provided U "is a" T.
    173   template <typename U>
    174   WeakPtr(const WeakPtr<U>& other) : WeakPtrBase(other), ptr_(other.get()) {
    175   }
    176 
    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 
    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 
    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:
    214   SupportsWeakPtr() {}
    215 
    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:
    233   explicit WeakPtrFactory(T* ptr) : ptr_(ptr) {
    234   }
    235 
    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.
    241   void InvalidateWeakPtrs() {
    242     weak_reference_owner_.Invalidate();
    243   }
    244 
    245   // Call this method to determine if any weak pointers exist.
    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