Home | History | Annotate | Download | only in memory
      1 // Copyright (c) 2011 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_MEMORY_WEAK_PTR_H_
     52 #define BASE_MEMORY_WEAK_PTR_H_
     53 #pragma once
     54 
     55 #include "base/base_api.h"
     56 #include "base/logging.h"
     57 #include "base/memory/ref_counted.h"
     58 #include "base/threading/thread_checker.h"
     59 
     60 namespace base {
     61 
     62 namespace internal {
     63 // These classes are part of the WeakPtr implementation.
     64 // DO NOT USE THESE CLASSES DIRECTLY YOURSELF.
     65 
     66 class BASE_API WeakReference {
     67  public:
     68   // While Flag is bound to a specific thread, it may be deleted from another
     69   // via base::WeakPtr::~WeakPtr().
     70   class Flag : public RefCountedThreadSafe<Flag> {
     71    public:
     72     explicit Flag(Flag** handle);
     73 
     74     void Invalidate();
     75     bool IsValid() const;
     76 
     77     void DetachFromThread() { thread_checker_.DetachFromThread(); }
     78 
     79    private:
     80     friend class base::RefCountedThreadSafe<Flag>;
     81 
     82     ~Flag();
     83 
     84     ThreadChecker thread_checker_;
     85     Flag** handle_;
     86   };
     87 
     88   WeakReference();
     89   WeakReference(Flag* flag);
     90   ~WeakReference();
     91 
     92   bool is_valid() const;
     93 
     94  private:
     95   scoped_refptr<Flag> flag_;
     96 };
     97 
     98 class BASE_API WeakReferenceOwner {
     99  public:
    100   WeakReferenceOwner();
    101   ~WeakReferenceOwner();
    102 
    103   WeakReference GetRef() const;
    104 
    105   bool HasRefs() const {
    106     return flag_ != NULL;
    107   }
    108 
    109   void Invalidate();
    110 
    111   // Indicates that this object will be used on another thread from now on.
    112   void DetachFromThread() {
    113     if (flag_) flag_->DetachFromThread();
    114   }
    115 
    116  private:
    117   mutable WeakReference::Flag* flag_;
    118 };
    119 
    120 // This class simplifies the implementation of WeakPtr's type conversion
    121 // constructor by avoiding the need for a public accessor for ref_.  A
    122 // WeakPtr<T> cannot access the private members of WeakPtr<U>, so this
    123 // base class gives us a way to access ref_ in a protected fashion.
    124 class BASE_API WeakPtrBase {
    125  public:
    126   WeakPtrBase();
    127   ~WeakPtrBase();
    128 
    129  protected:
    130   WeakPtrBase(const WeakReference& ref);
    131 
    132   WeakReference ref_;
    133 };
    134 
    135 }  // namespace internal
    136 
    137 template <typename T> class SupportsWeakPtr;
    138 template <typename T> class WeakPtrFactory;
    139 
    140 // The WeakPtr class holds a weak reference to |T*|.
    141 //
    142 // This class is designed to be used like a normal pointer.  You should always
    143 // null-test an object of this class before using it or invoking a method that
    144 // may result in the underlying object being destroyed.
    145 //
    146 // EXAMPLE:
    147 //
    148 //   class Foo { ... };
    149 //   WeakPtr<Foo> foo;
    150 //   if (foo)
    151 //     foo->method();
    152 //
    153 template <typename T>
    154 class WeakPtr : public internal::WeakPtrBase {
    155  public:
    156   WeakPtr() : ptr_(NULL) {
    157   }
    158 
    159   // Allow conversion from U to T provided U "is a" T.
    160   template <typename U>
    161   WeakPtr(const WeakPtr<U>& other) : WeakPtrBase(other), ptr_(other.get()) {
    162   }
    163 
    164   T* get() const { return ref_.is_valid() ? ptr_ : NULL; }
    165   operator T*() const { return get(); }
    166 
    167   T* operator*() const {
    168     DCHECK(get() != NULL);
    169     return *get();
    170   }
    171   T* operator->() const {
    172     DCHECK(get() != NULL);
    173     return get();
    174   }
    175 
    176   void reset() {
    177     ref_ = internal::WeakReference();
    178     ptr_ = NULL;
    179   }
    180 
    181  private:
    182   friend class SupportsWeakPtr<T>;
    183   friend class WeakPtrFactory<T>;
    184 
    185   WeakPtr(const internal::WeakReference& ref, T* ptr)
    186       : WeakPtrBase(ref), ptr_(ptr) {
    187   }
    188 
    189   // This pointer is only valid when ref_.is_valid() is true.  Otherwise, its
    190   // value is undefined (as opposed to NULL).
    191   T* ptr_;
    192 };
    193 
    194 // A class may extend from SupportsWeakPtr to expose weak pointers to itself.
    195 // This is useful in cases where you want others to be able to get a weak
    196 // pointer to your class.  It also has the property that you don't need to
    197 // initialize it from your constructor.
    198 template <class T>
    199 class SupportsWeakPtr {
    200  public:
    201   SupportsWeakPtr() {}
    202 
    203   WeakPtr<T> AsWeakPtr() {
    204     return WeakPtr<T>(weak_reference_owner_.GetRef(), static_cast<T*>(this));
    205   }
    206 
    207   // Indicates that this object will be used on another thread from now on.
    208   void DetachFromThread() {
    209     weak_reference_owner_.DetachFromThread();
    210   }
    211 
    212  private:
    213   internal::WeakReferenceOwner weak_reference_owner_;
    214   DISALLOW_COPY_AND_ASSIGN(SupportsWeakPtr);
    215 };
    216 
    217 // A class may alternatively be composed of a WeakPtrFactory and thereby
    218 // control how it exposes weak pointers to itself.  This is helpful if you only
    219 // need weak pointers within the implementation of a class.  This class is also
    220 // useful when working with primitive types.  For example, you could have a
    221 // WeakPtrFactory<bool> that is used to pass around a weak reference to a bool.
    222 template <class T>
    223 class WeakPtrFactory {
    224  public:
    225   explicit WeakPtrFactory(T* ptr) : ptr_(ptr) {
    226   }
    227 
    228   WeakPtr<T> GetWeakPtr() {
    229     return WeakPtr<T>(weak_reference_owner_.GetRef(), ptr_);
    230   }
    231 
    232   // Call this method to invalidate all existing weak pointers.
    233   void InvalidateWeakPtrs() {
    234     weak_reference_owner_.Invalidate();
    235   }
    236 
    237   // Call this method to determine if any weak pointers exist.
    238   bool HasWeakPtrs() const {
    239     return weak_reference_owner_.HasRefs();
    240   }
    241 
    242   // Indicates that this object will be used on another thread from now on.
    243   void DetachFromThread() {
    244     weak_reference_owner_.DetachFromThread();
    245   }
    246 
    247  private:
    248   internal::WeakReferenceOwner weak_reference_owner_;
    249   T* ptr_;
    250   DISALLOW_IMPLICIT_CONSTRUCTORS(WeakPtrFactory);
    251 };
    252 
    253 }  // namespace base
    254 
    255 #endif  // BASE_MEMORY_WEAK_PTR_H_
    256