ref_counted.h revision 5821806d5e7f356e8fa4b058a389a808ea183019
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 15namespace base { 16 17namespace subtle { 18 19class 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 43class 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. 81template <class T> 82class 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. 104template <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. 108template<typename T> 109struct 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(); 131template <class T, typename Traits = DefaultRefCountedThreadSafeTraits<T> > 132class 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 wrapper for some piece of data so we can place other things in 158// scoped_refptrs<>. 159// 160template<typename T> 161class RefCountedData : public base::RefCounted< base::RefCountedData<T> > { 162 public: 163 RefCountedData() : data() {} 164 RefCountedData(const T& in_value) : data(in_value) {} 165 166 T data; 167 168 private: 169 friend class base::RefCounted<base::RefCountedData<T> >; 170 ~RefCountedData() {} 171}; 172 173} // namespace base 174 175// 176// A smart pointer class for reference counted objects. Use this class instead 177// of calling AddRef and Release manually on a reference counted object to 178// avoid common memory leaks caused by forgetting to Release an object 179// reference. Sample usage: 180// 181// class MyFoo : public RefCounted<MyFoo> { 182// ... 183// }; 184// 185// void some_function() { 186// scoped_refptr<MyFoo> foo = new MyFoo(); 187// foo->Method(param); 188// // |foo| is released when this function returns 189// } 190// 191// void some_other_function() { 192// scoped_refptr<MyFoo> foo = new MyFoo(); 193// ... 194// foo = NULL; // explicitly releases |foo| 195// ... 196// if (foo) 197// foo->Method(param); 198// } 199// 200// The above examples show how scoped_refptr<T> acts like a pointer to T. 201// Given two scoped_refptr<T> classes, it is also possible to exchange 202// references between the two objects, like so: 203// 204// { 205// scoped_refptr<MyFoo> a = new MyFoo(); 206// scoped_refptr<MyFoo> b; 207// 208// b.swap(a); 209// // now, |b| references the MyFoo object, and |a| references NULL. 210// } 211// 212// To make both |a| and |b| in the above example reference the same MyFoo 213// object, simply use the assignment operator: 214// 215// { 216// scoped_refptr<MyFoo> a = new MyFoo(); 217// scoped_refptr<MyFoo> b; 218// 219// b = a; 220// // now, |a| and |b| each own a reference to the same MyFoo object. 221// } 222// 223template <class T> 224class scoped_refptr { 225 public: 226 typedef T element_type; 227 228 scoped_refptr() : ptr_(NULL) { 229 } 230 231 scoped_refptr(T* p) : ptr_(p) { 232 if (ptr_) 233 ptr_->AddRef(); 234 } 235 236 scoped_refptr(const scoped_refptr<T>& r) : ptr_(r.ptr_) { 237 if (ptr_) 238 ptr_->AddRef(); 239 } 240 241 template <typename U> 242 scoped_refptr(const scoped_refptr<U>& r) : ptr_(r.get()) { 243 if (ptr_) 244 ptr_->AddRef(); 245 } 246 247 ~scoped_refptr() { 248 if (ptr_) 249 ptr_->Release(); 250 } 251 252 T* get() const { return ptr_; } 253 operator T*() const { return ptr_; } 254 T* operator->() const { 255 assert(ptr_ != NULL); 256 return ptr_; 257 } 258 259 // Release a pointer. 260 // The return value is the current pointer held by this object. 261 // If this object holds a NULL pointer, the return value is NULL. 262 // After this operation, this object will hold a NULL pointer, 263 // and will not own the object any more. 264 T* release() WARN_UNUSED_RESULT { 265 T* retVal = ptr_; 266 ptr_ = NULL; 267 return retVal; 268 } 269 270 scoped_refptr<T>& operator=(T* p) { 271 // AddRef first so that self assignment should work 272 if (p) 273 p->AddRef(); 274 T* old_ptr = ptr_; 275 ptr_ = p; 276 if (old_ptr) 277 old_ptr->Release(); 278 return *this; 279 } 280 281 scoped_refptr<T>& operator=(const scoped_refptr<T>& r) { 282 return *this = r.ptr_; 283 } 284 285 template <typename U> 286 scoped_refptr<T>& operator=(const scoped_refptr<U>& r) { 287 return *this = r.get(); 288 } 289 290 void swap(T** pp) { 291 T* p = ptr_; 292 ptr_ = *pp; 293 *pp = p; 294 } 295 296 void swap(scoped_refptr<T>& r) { 297 swap(&r.ptr_); 298 } 299 300 protected: 301 T* ptr_; 302}; 303 304// Handy utility for creating a scoped_refptr<T> out of a T* explicitly without 305// having to retype all the template arguments 306template <typename T> 307scoped_refptr<T> make_scoped_refptr(T* t) { 308 return scoped_refptr<T>(t); 309} 310 311#endif // BASE_MEMORY_REF_COUNTED_H_ 312