Home | History | Annotate | Download | only in base
      1 // Copyright (c) 2006-2008 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 #ifndef BASE_REF_COUNTED_H_
      6 #define BASE_REF_COUNTED_H_
      7 
      8 #include "base/atomic_ref_count.h"
      9 #include "base/thread_collision_warner.h"
     10 
     11 namespace base {
     12 
     13 namespace subtle {
     14 
     15 class RefCountedBase {
     16  public:
     17   static bool ImplementsThreadSafeReferenceCounting() { return false; }
     18 
     19   bool HasOneRef() const { return ref_count_ == 1; }
     20 
     21  protected:
     22   RefCountedBase();
     23   ~RefCountedBase();
     24 
     25   void AddRef();
     26 
     27   // Returns true if the object should self-delete.
     28   bool Release();
     29 
     30  private:
     31   int ref_count_;
     32 #ifndef NDEBUG
     33   bool in_dtor_;
     34 #endif
     35 
     36   DFAKE_MUTEX(add_release_);
     37 
     38   DISALLOW_COPY_AND_ASSIGN(RefCountedBase);
     39 };
     40 
     41 class RefCountedThreadSafeBase {
     42  public:
     43   static bool ImplementsThreadSafeReferenceCounting() { return true; }
     44 
     45   bool HasOneRef() const;
     46 
     47  protected:
     48   RefCountedThreadSafeBase();
     49   ~RefCountedThreadSafeBase();
     50 
     51   void AddRef();
     52 
     53   // Returns true if the object should self-delete.
     54   bool Release();
     55 
     56  private:
     57   AtomicRefCount ref_count_;
     58 #ifndef NDEBUG
     59   bool in_dtor_;
     60 #endif
     61 
     62   DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafeBase);
     63 };
     64 
     65 }  // namespace subtle
     66 
     67 //
     68 // A base class for reference counted classes.  Otherwise, known as a cheap
     69 // knock-off of WebKit's RefCounted<T> class.  To use this guy just extend your
     70 // class from it like so:
     71 //
     72 //   class MyFoo : public base::RefCounted<MyFoo> {
     73 //    ...
     74 //    private:
     75 //     friend class base::RefCounted<MyFoo>;
     76 //     ~MyFoo();
     77 //   };
     78 //
     79 // You should always make your destructor private, to avoid any code deleting
     80 // the object accidently while there are references to it.
     81 template <class T>
     82 class RefCounted : public subtle::RefCountedBase {
     83  public:
     84   RefCounted() { }
     85   ~RefCounted() { }
     86 
     87   void AddRef() {
     88     subtle::RefCountedBase::AddRef();
     89   }
     90 
     91   void Release() {
     92     if (subtle::RefCountedBase::Release()) {
     93       delete static_cast<T*>(this);
     94     }
     95   }
     96 
     97  private:
     98   DISALLOW_COPY_AND_ASSIGN(RefCounted<T>);
     99 };
    100 
    101 // Forward declaration.
    102 template <class T, typename Traits> class RefCountedThreadSafe;
    103 
    104 // Default traits for RefCountedThreadSafe<T>.  Deletes the object when its ref
    105 // count reaches 0.  Overload to delete it on a different thread etc.
    106 template<typename T>
    107 struct DefaultRefCountedThreadSafeTraits {
    108   static void Destruct(T* x) {
    109     // Delete through RefCountedThreadSafe to make child classes only need to be
    110     // friend with RefCountedThreadSafe instead of this struct, which is an
    111     // implementation detail.
    112     RefCountedThreadSafe<T, DefaultRefCountedThreadSafeTraits>::DeleteInternal(x);
    113   }
    114 };
    115 
    116 //
    117 // A thread-safe variant of RefCounted<T>
    118 //
    119 //   class MyFoo : public base::RefCountedThreadSafe<MyFoo> {
    120 //    ...
    121 //   };
    122 //
    123 // If you're using the default trait, then you should add compile time
    124 // asserts that no one else is deleting your object.  i.e.
    125 //    private:
    126 //     friend class base::RefCountedThreadSafe<MyFoo>;
    127 //     ~MyFoo();
    128 template <class T, typename Traits = DefaultRefCountedThreadSafeTraits<T> >
    129 class RefCountedThreadSafe : public subtle::RefCountedThreadSafeBase {
    130  public:
    131   RefCountedThreadSafe() { }
    132   ~RefCountedThreadSafe() { }
    133 
    134   void AddRef() {
    135     subtle::RefCountedThreadSafeBase::AddRef();
    136   }
    137 
    138   void Release() {
    139     if (subtle::RefCountedThreadSafeBase::Release()) {
    140       Traits::Destruct(static_cast<T*>(this));
    141     }
    142   }
    143 
    144  private:
    145   friend struct DefaultRefCountedThreadSafeTraits<T>;
    146   static void DeleteInternal(T* x) { delete x; }
    147 
    148   DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafe);
    149 };
    150 
    151 //
    152 // A wrapper for some piece of data so we can place other things in
    153 // scoped_refptrs<>.
    154 //
    155 template<typename T>
    156 class RefCountedData : public base::RefCounted< base::RefCountedData<T> > {
    157  public:
    158   RefCountedData() : data() {}
    159   RefCountedData(const T& in_value) : data(in_value) {}
    160 
    161   T data;
    162 };
    163 
    164 }  // namespace base
    165 
    166 //
    167 // A smart pointer class for reference counted objects.  Use this class instead
    168 // of calling AddRef and Release manually on a reference counted object to
    169 // avoid common memory leaks caused by forgetting to Release an object
    170 // reference.  Sample usage:
    171 //
    172 //   class MyFoo : public RefCounted<MyFoo> {
    173 //    ...
    174 //   };
    175 //
    176 //   void some_function() {
    177 //     scoped_refptr<MyFoo> foo = new MyFoo();
    178 //     foo->Method(param);
    179 //     // |foo| is released when this function returns
    180 //   }
    181 //
    182 //   void some_other_function() {
    183 //     scoped_refptr<MyFoo> foo = new MyFoo();
    184 //     ...
    185 //     foo = NULL;  // explicitly releases |foo|
    186 //     ...
    187 //     if (foo)
    188 //       foo->Method(param);
    189 //   }
    190 //
    191 // The above examples show how scoped_refptr<T> acts like a pointer to T.
    192 // Given two scoped_refptr<T> classes, it is also possible to exchange
    193 // references between the two objects, like so:
    194 //
    195 //   {
    196 //     scoped_refptr<MyFoo> a = new MyFoo();
    197 //     scoped_refptr<MyFoo> b;
    198 //
    199 //     b.swap(a);
    200 //     // now, |b| references the MyFoo object, and |a| references NULL.
    201 //   }
    202 //
    203 // To make both |a| and |b| in the above example reference the same MyFoo
    204 // object, simply use the assignment operator:
    205 //
    206 //   {
    207 //     scoped_refptr<MyFoo> a = new MyFoo();
    208 //     scoped_refptr<MyFoo> b;
    209 //
    210 //     b = a;
    211 //     // now, |a| and |b| each own a reference to the same MyFoo object.
    212 //   }
    213 //
    214 template <class T>
    215 class scoped_refptr {
    216  public:
    217   scoped_refptr() : ptr_(NULL) {
    218   }
    219 
    220   scoped_refptr(T* p) : ptr_(p) {
    221     if (ptr_)
    222       ptr_->AddRef();
    223   }
    224 
    225   scoped_refptr(const scoped_refptr<T>& r) : ptr_(r.ptr_) {
    226     if (ptr_)
    227       ptr_->AddRef();
    228   }
    229 
    230   template <typename U>
    231   scoped_refptr(const scoped_refptr<U>& r) : ptr_(r.get()) {
    232     if (ptr_)
    233       ptr_->AddRef();
    234   }
    235 
    236   ~scoped_refptr() {
    237     if (ptr_)
    238       ptr_->Release();
    239   }
    240 
    241   T* get() const { return ptr_; }
    242   operator T*() const { return ptr_; }
    243   T* operator->() const { return ptr_; }
    244 
    245   // Release a pointer.
    246   // The return value is the current pointer held by this object.
    247   // If this object holds a NULL pointer, the return value is NULL.
    248   // After this operation, this object will hold a NULL pointer,
    249   // and will not own the object any more.
    250   T* release() {
    251     T* retVal = ptr_;
    252     ptr_ = NULL;
    253     return retVal;
    254   }
    255 
    256   scoped_refptr<T>& operator=(T* p) {
    257     // AddRef first so that self assignment should work
    258     if (p)
    259       p->AddRef();
    260     if (ptr_ )
    261       ptr_ ->Release();
    262     ptr_ = p;
    263     return *this;
    264   }
    265 
    266   scoped_refptr<T>& operator=(const scoped_refptr<T>& r) {
    267     return *this = r.ptr_;
    268   }
    269 
    270   template <typename U>
    271   scoped_refptr<T>& operator=(const scoped_refptr<U>& r) {
    272     return *this = r.get();
    273   }
    274 
    275   void swap(T** pp) {
    276     T* p = ptr_;
    277     ptr_ = *pp;
    278     *pp = p;
    279   }
    280 
    281   void swap(scoped_refptr<T>& r) {
    282     swap(&r.ptr_);
    283   }
    284 
    285  protected:
    286   T* ptr_;
    287 };
    288 
    289 // Handy utility for creating a scoped_refptr<T> out of a T* explicitly without
    290 // having to retype all the template arguments
    291 template <typename T>
    292 scoped_refptr<T> make_scoped_refptr(T* t) {
    293   return scoped_refptr<T>(t);
    294 }
    295 
    296 #endif  // BASE_REF_COUNTED_H_
    297