ref_counted.h revision c2cbc7df84951541b29200c3a6ade3163fb815ae
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 13namespace base { 14 15namespace subtle { 16 17class 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 43class 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. 83template <class T> 84class 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. 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 ~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// 158template<typename T> 159class 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// 217template <class T> 218class 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 295template <typename T> 296scoped_refptr<T> make_scoped_refptr(T* t) { 297 return scoped_refptr<T>(t); 298} 299 300#endif // BASE_MEMORY_REF_COUNTED_H_ 301