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