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 <atomic> 9 #include <cassert> 10 #include <iosfwd> 11 12 #include "base/base_export.h" 13 #include "base/compiler_specific.h" 14 #include "base/macros.h" 15 #include "base/logging.h" 16 #include "build/build_config.h" 17 18 namespace base { 19 20 namespace subtle { 21 22 class BASE_EXPORT RefCountedBase { 23 public: HasOneRef()24 bool HasOneRef() const { return ref_count_ == 1; } 25 26 protected: RefCountedBase()27 RefCountedBase() 28 : ref_count_(0) 29 #ifndef NDEBUG 30 , in_dtor_(false) 31 #endif 32 { 33 } 34 ~RefCountedBase()35 ~RefCountedBase() { 36 #ifndef NDEBUG 37 DCHECK(in_dtor_) << "RefCounted object deleted without calling Release()"; 38 #endif 39 } 40 41 AddRef()42 void AddRef() const { 43 #ifndef NDEBUG 44 DCHECK(!in_dtor_); 45 #endif 46 ++ref_count_; 47 } 48 49 // Returns true if the object should self-delete. Release()50 bool Release() const { 51 #ifndef NDEBUG 52 DCHECK(!in_dtor_); 53 #endif 54 if (--ref_count_ == 0) { 55 #ifndef NDEBUG 56 in_dtor_ = true; 57 #endif 58 return true; 59 } 60 return false; 61 } 62 63 private: 64 mutable int ref_count_; 65 #ifndef NDEBUG 66 mutable bool in_dtor_; 67 #endif 68 69 DISALLOW_COPY_AND_ASSIGN(RefCountedBase); 70 }; 71 72 class BASE_EXPORT RefCountedThreadSafeBase { 73 public: 74 bool HasOneRef() const; 75 76 protected: 77 RefCountedThreadSafeBase(); 78 ~RefCountedThreadSafeBase(); 79 80 void AddRef() const; 81 82 // Returns true if the object should self-delete. 83 bool Release() const; 84 85 private: 86 mutable std::atomic<int32_t> ref_count_; 87 #ifndef NDEBUG 88 mutable bool in_dtor_; 89 #endif 90 91 DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafeBase); 92 }; 93 94 } // namespace subtle 95 96 // 97 // A base class for reference counted classes. Otherwise, known as a cheap 98 // knock-off of WebKit's RefCounted<T> class. To use this guy just extend your 99 // class from it like so: 100 // 101 // class MyFoo : public base::RefCounted<MyFoo> { 102 // ... 103 // private: 104 // friend class base::RefCounted<MyFoo>; 105 // ~MyFoo(); 106 // }; 107 // 108 // You should always make your destructor non-public, to avoid any code deleting 109 // the object accidently while there are references to it. 110 template <class T> 111 class RefCounted : public subtle::RefCountedBase { 112 public: RefCounted()113 RefCounted() {} 114 AddRef()115 void AddRef() const { 116 subtle::RefCountedBase::AddRef(); 117 } 118 Release()119 void Release() const { 120 if (subtle::RefCountedBase::Release()) { 121 delete static_cast<const T*>(this); 122 } 123 } 124 125 protected: ~RefCounted()126 ~RefCounted() {} 127 128 private: 129 DISALLOW_COPY_AND_ASSIGN(RefCounted<T>); 130 }; 131 132 // Forward declaration. 133 template <class T, typename Traits> class RefCountedThreadSafe; 134 135 // Default traits for RefCountedThreadSafe<T>. Deletes the object when its ref 136 // count reaches 0. Overload to delete it on a different thread etc. 137 template<typename T> 138 struct DefaultRefCountedThreadSafeTraits { DestructDefaultRefCountedThreadSafeTraits139 static void Destruct(const T* x) { 140 // Delete through RefCountedThreadSafe to make child classes only need to be 141 // friend with RefCountedThreadSafe instead of this struct, which is an 142 // implementation detail. 143 RefCountedThreadSafe<T, 144 DefaultRefCountedThreadSafeTraits>::DeleteInternal(x); 145 } 146 }; 147 148 // 149 // A thread-safe variant of RefCounted<T> 150 // 151 // class MyFoo : public base::RefCountedThreadSafe<MyFoo> { 152 // ... 153 // }; 154 // 155 // If you're using the default trait, then you should add compile time 156 // asserts that no one else is deleting your object. i.e. 157 // private: 158 // friend class base::RefCountedThreadSafe<MyFoo>; 159 // ~MyFoo(); 160 template <class T, typename Traits = DefaultRefCountedThreadSafeTraits<T> > 161 class RefCountedThreadSafe : public subtle::RefCountedThreadSafeBase { 162 public: RefCountedThreadSafe()163 RefCountedThreadSafe() {} 164 AddRef()165 void AddRef() const { 166 subtle::RefCountedThreadSafeBase::AddRef(); 167 } 168 Release()169 void Release() const { 170 if (subtle::RefCountedThreadSafeBase::Release()) { 171 Traits::Destruct(static_cast<const T*>(this)); 172 } 173 } 174 175 protected: ~RefCountedThreadSafe()176 ~RefCountedThreadSafe() {} 177 178 private: 179 friend struct DefaultRefCountedThreadSafeTraits<T>; 180 static void DeleteInternal(const T* x) { delete x; } 181 182 DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafe); 183 }; 184 185 // 186 // A thread-safe wrapper for some piece of data so we can place other 187 // things in scoped_refptrs<>. 188 // 189 template<typename T> 190 class RefCountedData 191 : public base::RefCountedThreadSafe< base::RefCountedData<T> > { 192 public: 193 RefCountedData() : data() {} 194 RefCountedData(const T& in_value) : data(in_value) {} 195 196 T data; 197 198 private: 199 friend class base::RefCountedThreadSafe<base::RefCountedData<T> >; 200 ~RefCountedData() {} 201 }; 202 203 } // namespace base 204 205 // 206 // A smart pointer class for reference counted objects. Use this class instead 207 // of calling AddRef and Release manually on a reference counted object to 208 // avoid common memory leaks caused by forgetting to Release an object 209 // reference. Sample usage: 210 // 211 // class MyFoo : public RefCounted<MyFoo> { 212 // ... 213 // }; 214 // 215 // void some_function() { 216 // scoped_refptr<MyFoo> foo = new MyFoo(); 217 // foo->Method(param); 218 // // |foo| is released when this function returns 219 // } 220 // 221 // void some_other_function() { 222 // scoped_refptr<MyFoo> foo = new MyFoo(); 223 // ... 224 // foo = NULL; // explicitly releases |foo| 225 // ... 226 // if (foo) 227 // foo->Method(param); 228 // } 229 // 230 // The above examples show how scoped_refptr<T> acts like a pointer to T. 231 // Given two scoped_refptr<T> classes, it is also possible to exchange 232 // references between the two objects, like so: 233 // 234 // { 235 // scoped_refptr<MyFoo> a = new MyFoo(); 236 // scoped_refptr<MyFoo> b; 237 // 238 // b.swap(a); 239 // // now, |b| references the MyFoo object, and |a| references NULL. 240 // } 241 // 242 // To make both |a| and |b| in the above example reference the same MyFoo 243 // object, simply use the assignment operator: 244 // 245 // { 246 // scoped_refptr<MyFoo> a = new MyFoo(); 247 // scoped_refptr<MyFoo> b; 248 // 249 // b = a; 250 // // now, |a| and |b| each own a reference to the same MyFoo object. 251 // } 252 // 253 template <class T> 254 class scoped_refptr { 255 public: 256 typedef T element_type; 257 258 scoped_refptr() : ptr_(NULL) { 259 } 260 261 scoped_refptr(T* p) : ptr_(p) { 262 if (ptr_) 263 AddRef(ptr_); 264 } 265 266 // Copy constructor. 267 scoped_refptr(const scoped_refptr<T>& r) : ptr_(r.ptr_) { 268 if (ptr_) 269 AddRef(ptr_); 270 } 271 272 // Copy conversion constructor. 273 template <typename U> 274 scoped_refptr(const scoped_refptr<U>& r) : ptr_(r.get()) { 275 if (ptr_) 276 AddRef(ptr_); 277 } 278 279 // Move constructor. This is required in addition to the conversion 280 // constructor below in order for clang to warn about pessimizing moves. 281 scoped_refptr(scoped_refptr&& r) : ptr_(r.get()) { r.ptr_ = nullptr; } 282 283 // Move conversion constructor. 284 template <typename U> 285 scoped_refptr(scoped_refptr<U>&& r) : ptr_(r.get()) { 286 r.ptr_ = nullptr; 287 } 288 289 ~scoped_refptr() { 290 if (ptr_) 291 Release(ptr_); 292 } 293 294 T* get() const { return ptr_; } 295 296 T& operator*() const { 297 assert(ptr_ != NULL); 298 return *ptr_; 299 } 300 301 T* operator->() const { 302 assert(ptr_ != NULL); 303 return ptr_; 304 } 305 306 scoped_refptr<T>& operator=(T* p) { 307 // AddRef first so that self assignment should work 308 if (p) 309 AddRef(p); 310 T* old_ptr = ptr_; 311 ptr_ = p; 312 if (old_ptr) 313 Release(old_ptr); 314 return *this; 315 } 316 317 scoped_refptr<T>& operator=(const scoped_refptr<T>& r) { 318 return *this = r.ptr_; 319 } 320 321 template <typename U> 322 scoped_refptr<T>& operator=(const scoped_refptr<U>& r) { 323 return *this = r.get(); 324 } 325 326 scoped_refptr<T>& operator=(scoped_refptr<T>&& r) { 327 scoped_refptr<T>(std::move(r)).swap(*this); 328 return *this; 329 } 330 331 template <typename U> 332 scoped_refptr<T>& operator=(scoped_refptr<U>&& r) { 333 scoped_refptr<T>(std::move(r)).swap(*this); 334 return *this; 335 } 336 337 void swap(T** pp) { 338 T* p = ptr_; 339 ptr_ = *pp; 340 *pp = p; 341 } 342 343 void swap(scoped_refptr<T>& r) { 344 swap(&r.ptr_); 345 } 346 347 private: 348 template <typename U> friend class scoped_refptr; 349 350 // Allow scoped_refptr<T> to be used in boolean expressions, but not 351 // implicitly convertible to a real bool (which is dangerous). 352 // 353 // Note that this trick is only safe when the == and != operators 354 // are declared explicitly, as otherwise "refptr1 == refptr2" 355 // will compile but do the wrong thing (i.e., convert to Testable 356 // and then do the comparison). 357 typedef T* scoped_refptr::*Testable; 358 359 public: 360 operator Testable() const { return ptr_ ? &scoped_refptr::ptr_ : nullptr; } 361 362 template <typename U> 363 bool operator==(const scoped_refptr<U>& rhs) const { 364 return ptr_ == rhs.get(); 365 } 366 367 template <typename U> 368 bool operator!=(const scoped_refptr<U>& rhs) const { 369 return !operator==(rhs); 370 } 371 372 template <typename U> 373 bool operator<(const scoped_refptr<U>& rhs) const { 374 return ptr_ < rhs.get(); 375 } 376 377 protected: 378 T* ptr_; 379 380 private: 381 // Non-inline helpers to allow: 382 // class Opaque; 383 // extern template class scoped_refptr<Opaque>; 384 // Otherwise the compiler will complain that Opaque is an incomplete type. 385 static void AddRef(T* ptr); 386 static void Release(T* ptr); 387 }; 388 389 template <typename T> 390 void scoped_refptr<T>::AddRef(T* ptr) { 391 ptr->AddRef(); 392 } 393 394 template <typename T> 395 void scoped_refptr<T>::Release(T* ptr) { 396 ptr->Release(); 397 } 398 399 // Handy utility for creating a scoped_refptr<T> out of a T* explicitly without 400 // having to retype all the template arguments 401 template <typename T> 402 scoped_refptr<T> make_scoped_refptr(T* t) { 403 return scoped_refptr<T>(t); 404 } 405 406 // Temporary operator overloads to facilitate the transition. See 407 // https://crbug.com/110610. 408 template <typename T, typename U> 409 bool operator==(const scoped_refptr<T>& lhs, const U* rhs) { 410 return lhs.get() == rhs; 411 } 412 413 template <typename T, typename U> 414 bool operator==(const T* lhs, const scoped_refptr<U>& rhs) { 415 return lhs == rhs.get(); 416 } 417 418 template <typename T, typename U> 419 bool operator!=(const scoped_refptr<T>& lhs, const U* rhs) { 420 return !operator==(lhs, rhs); 421 } 422 423 template <typename T, typename U> 424 bool operator!=(const T* lhs, const scoped_refptr<U>& rhs) { 425 return !operator==(lhs, rhs); 426 } 427 428 template <typename T> 429 std::ostream& operator<<(std::ostream& out, const scoped_refptr<T>& p) { 430 return out << p.get(); 431 } 432 433 #endif // BASE_MEMORY_REF_COUNTED_H_ 434