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