1 // Copyright (c) 2012 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 8 #include <cassert> 9 10 #include "base/atomic_ref_count.h" 11 #include "base/base_export.h" 12 #include "base/compiler_specific.h" 13 #include "base/threading/thread_collision_warner.h" 14 15 namespace base { 16 17 namespace subtle { 18 19 class BASE_EXPORT RefCountedBase { 20 public: 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_EXPORT RefCountedThreadSafeBase { 44 public: 45 bool HasOneRef() const; 46 47 protected: 48 RefCountedThreadSafeBase(); 49 ~RefCountedThreadSafeBase(); 50 51 void AddRef() const; 52 53 // Returns true if the object should self-delete. 54 bool Release() const; 55 56 private: 57 mutable AtomicRefCount ref_count_; 58 #ifndef NDEBUG 59 mutable 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 86 void AddRef() const { 87 subtle::RefCountedBase::AddRef(); 88 } 89 90 void Release() const { 91 if (subtle::RefCountedBase::Release()) { 92 delete static_cast<const T*>(this); 93 } 94 } 95 96 protected: 97 ~RefCounted() {} 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 136 void AddRef() const { 137 subtle::RefCountedThreadSafeBase::AddRef(); 138 } 139 140 void Release() const { 141 if (subtle::RefCountedThreadSafeBase::Release()) { 142 Traits::Destruct(static_cast<const T*>(this)); 143 } 144 } 145 146 protected: 147 ~RefCountedThreadSafe() {} 148 149 private: 150 friend struct DefaultRefCountedThreadSafeTraits<T>; 151 static void DeleteInternal(const T* x) { delete x; } 152 153 DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafe); 154 }; 155 156 // 157 // A thread-safe wrapper for some piece of data so we can place other 158 // things in scoped_refptrs<>. 159 // 160 template<typename T> 161 class RefCountedData 162 : public base::RefCountedThreadSafe< base::RefCountedData<T> > { 163 public: 164 RefCountedData() : data() {} 165 RefCountedData(const T& in_value) : data(in_value) {} 166 167 T data; 168 169 private: 170 friend class base::RefCountedThreadSafe<base::RefCountedData<T> >; 171 ~RefCountedData() {} 172 }; 173 174 } // namespace base 175 176 // 177 // A smart pointer class for reference counted objects. Use this class instead 178 // of calling AddRef and Release manually on a reference counted object to 179 // avoid common memory leaks caused by forgetting to Release an object 180 // reference. Sample usage: 181 // 182 // class MyFoo : public RefCounted<MyFoo> { 183 // ... 184 // }; 185 // 186 // void some_function() { 187 // scoped_refptr<MyFoo> foo = new MyFoo(); 188 // foo->Method(param); 189 // // |foo| is released when this function returns 190 // } 191 // 192 // void some_other_function() { 193 // scoped_refptr<MyFoo> foo = new MyFoo(); 194 // ... 195 // foo = NULL; // explicitly releases |foo| 196 // ... 197 // if (foo) 198 // foo->Method(param); 199 // } 200 // 201 // The above examples show how scoped_refptr<T> acts like a pointer to T. 202 // Given two scoped_refptr<T> classes, it is also possible to exchange 203 // references between the two objects, like so: 204 // 205 // { 206 // scoped_refptr<MyFoo> a = new MyFoo(); 207 // scoped_refptr<MyFoo> b; 208 // 209 // b.swap(a); 210 // // now, |b| references the MyFoo object, and |a| references NULL. 211 // } 212 // 213 // To make both |a| and |b| in the above example reference the same MyFoo 214 // object, simply use the assignment operator: 215 // 216 // { 217 // scoped_refptr<MyFoo> a = new MyFoo(); 218 // scoped_refptr<MyFoo> b; 219 // 220 // b = a; 221 // // now, |a| and |b| each own a reference to the same MyFoo object. 222 // } 223 // 224 template <class T> 225 class scoped_refptr { 226 public: 227 typedef T element_type; 228 229 scoped_refptr() : ptr_(NULL) { 230 } 231 232 scoped_refptr(T* p) : ptr_(p) { 233 if (ptr_) 234 ptr_->AddRef(); 235 } 236 237 scoped_refptr(const scoped_refptr<T>& r) : ptr_(r.ptr_) { 238 if (ptr_) 239 ptr_->AddRef(); 240 } 241 242 template <typename U> 243 scoped_refptr(const scoped_refptr<U>& r) : ptr_(r.get()) { 244 if (ptr_) 245 ptr_->AddRef(); 246 } 247 248 ~scoped_refptr() { 249 if (ptr_) 250 ptr_->Release(); 251 } 252 253 T* get() const { return ptr_; } 254 255 // Allow scoped_refptr<C> to be used in boolean expression 256 // and comparison operations. 257 operator T*() const { return ptr_; } 258 259 T* operator->() const { 260 assert(ptr_ != NULL); 261 return ptr_; 262 } 263 264 scoped_refptr<T>& operator=(T* p) { 265 // AddRef first so that self assignment should work 266 if (p) 267 p->AddRef(); 268 T* old_ptr = ptr_; 269 ptr_ = p; 270 if (old_ptr) 271 old_ptr->Release(); 272 return *this; 273 } 274 275 scoped_refptr<T>& operator=(const scoped_refptr<T>& r) { 276 return *this = r.ptr_; 277 } 278 279 template <typename U> 280 scoped_refptr<T>& operator=(const scoped_refptr<U>& r) { 281 return *this = r.get(); 282 } 283 284 void swap(T** pp) { 285 T* p = ptr_; 286 ptr_ = *pp; 287 *pp = p; 288 } 289 290 void swap(scoped_refptr<T>& r) { 291 swap(&r.ptr_); 292 } 293 294 protected: 295 T* ptr_; 296 }; 297 298 // Handy utility for creating a scoped_refptr<T> out of a T* explicitly without 299 // having to retype all the template arguments 300 template <typename T> 301 scoped_refptr<T> make_scoped_refptr(T* t) { 302 return scoped_refptr<T>(t); 303 } 304 305 #endif // BASE_MEMORY_REF_COUNTED_H_ 306