15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef BASE_MEMORY_REF_COUNTED_H_ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define BASE_MEMORY_REF_COUNTED_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <cassert> 91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <iosfwd> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/atomic_ref_count.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/base_export.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 14a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#ifndef NDEBUG 15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/logging.h" 16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#endif 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread_collision_warner.h" 181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "build/build_config.h" 191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(OS_LINUX) || (defined(OS_MACOSX) && !defined(OS_IOS)) 211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#define DISABLE_SCOPED_REFPTR_CONVERSION_OPERATOR 221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace subtle { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BASE_EXPORT RefCountedBase { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool HasOneRef() const { return ref_count_ == 1; } 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 33a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) RefCountedBase() 34a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) : ref_count_(0) 35a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) #ifndef NDEBUG 36a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) , in_dtor_(false) 37a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) #endif 38a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) { 39a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 40a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 41a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ~RefCountedBase() { 42a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) #ifndef NDEBUG 43a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK(in_dtor_) << "RefCounted object deleted without calling Release()"; 44a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) #endif 45a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 46a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 47a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 48a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) void AddRef() const { 49a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // TODO(maruel): Add back once it doesn't assert 500 times/sec. 50a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Current thread books the critical section "AddRelease" 51a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // without release it. 52a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // DFAKE_SCOPED_LOCK_THREAD_LOCKED(add_release_); 53a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) #ifndef NDEBUG 54a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK(!in_dtor_); 55a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) #endif 56a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ++ref_count_; 57a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if the object should self-delete. 60a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool Release() const { 61a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // TODO(maruel): Add back once it doesn't assert 500 times/sec. 62a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Current thread books the critical section "AddRelease" 63a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // without release it. 64a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // DFAKE_SCOPED_LOCK_THREAD_LOCKED(add_release_); 65a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) #ifndef NDEBUG 66a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) DCHECK(!in_dtor_); 67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) #endif 68a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (--ref_count_ == 0) { 69a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) #ifndef NDEBUG 70a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) in_dtor_ = true; 71a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) #endif 72a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return true; 73a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 74a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return false; 75a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mutable int ref_count_; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NDEBUG 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mutable bool in_dtor_; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DFAKE_MUTEX(add_release_); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(RefCountedBase); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BASE_EXPORT RefCountedThreadSafeBase { 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool HasOneRef() const; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RefCountedThreadSafeBase(); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~RefCountedThreadSafeBase(); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AddRef() const; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if the object should self-delete. 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool Release() const; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mutable AtomicRefCount ref_count_; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NDEBUG 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mutable bool in_dtor_; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafeBase); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace subtle 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A base class for reference counted classes. Otherwise, known as a cheap 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// knock-off of WebKit's RefCounted<T> class. To use this guy just extend your 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// class from it like so: 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// class MyFoo : public base::RefCounted<MyFoo> { 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ... 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// private: 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// friend class base::RefCounted<MyFoo>; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ~MyFoo(); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// }; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// You should always make your destructor private, to avoid any code deleting 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the object accidently while there are references to it. 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class T> 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class RefCounted : public subtle::RefCountedBase { 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RefCounted() {} 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AddRef() const { 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) subtle::RefCountedBase::AddRef(); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Release() const { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (subtle::RefCountedBase::Release()) { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete static_cast<const T*>(this); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~RefCounted() {} 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(RefCounted<T>); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Forward declaration. 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class T, typename Traits> class RefCountedThreadSafe; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Default traits for RefCountedThreadSafe<T>. Deletes the object when its ref 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// count reaches 0. Overload to delete it on a different thread etc. 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename T> 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct DefaultRefCountedThreadSafeTraits { 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void Destruct(const T* x) { 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Delete through RefCountedThreadSafe to make child classes only need to be 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // friend with RefCountedThreadSafe instead of this struct, which is an 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // implementation detail. 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RefCountedThreadSafe<T, 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DefaultRefCountedThreadSafeTraits>::DeleteInternal(x); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A thread-safe variant of RefCounted<T> 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// class MyFoo : public base::RefCountedThreadSafe<MyFoo> { 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ... 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// }; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If you're using the default trait, then you should add compile time 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// asserts that no one else is deleting your object. i.e. 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// private: 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// friend class base::RefCountedThreadSafe<MyFoo>; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ~MyFoo(); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class T, typename Traits = DefaultRefCountedThreadSafeTraits<T> > 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class RefCountedThreadSafe : public subtle::RefCountedThreadSafeBase { 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RefCountedThreadSafe() {} 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AddRef() const { 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) subtle::RefCountedThreadSafeBase::AddRef(); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Release() const { 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (subtle::RefCountedThreadSafeBase::Release()) { 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Traits::Destruct(static_cast<const T*>(this)); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~RefCountedThreadSafe() {} 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend struct DefaultRefCountedThreadSafeTraits<T>; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void DeleteInternal(const T* x) { delete x; } 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafe); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// A thread-safe wrapper for some piece of data so we can place other 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// things in scoped_refptrs<>. 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename T> 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class RefCountedData 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : public base::RefCountedThreadSafe< base::RefCountedData<T> > { 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RefCountedData() : data() {} 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RefCountedData(const T& in_value) : data(in_value) {} 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) T data; 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) friend class base::RefCountedThreadSafe<base::RefCountedData<T> >; 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~RefCountedData() {} 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace base 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A smart pointer class for reference counted objects. Use this class instead 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of calling AddRef and Release manually on a reference counted object to 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// avoid common memory leaks caused by forgetting to Release an object 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// reference. Sample usage: 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// class MyFoo : public RefCounted<MyFoo> { 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ... 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// }; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// void some_function() { 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// scoped_refptr<MyFoo> foo = new MyFoo(); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// foo->Method(param); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// // |foo| is released when this function returns 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// } 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// void some_other_function() { 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// scoped_refptr<MyFoo> foo = new MyFoo(); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ... 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// foo = NULL; // explicitly releases |foo| 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ... 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// if (foo) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// foo->Method(param); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// } 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The above examples show how scoped_refptr<T> acts like a pointer to T. 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Given two scoped_refptr<T> classes, it is also possible to exchange 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// references between the two objects, like so: 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// { 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// scoped_refptr<MyFoo> a = new MyFoo(); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// scoped_refptr<MyFoo> b; 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// b.swap(a); 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// // now, |b| references the MyFoo object, and |a| references NULL. 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// } 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// To make both |a| and |b| in the above example reference the same MyFoo 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// object, simply use the assignment operator: 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// { 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// scoped_refptr<MyFoo> a = new MyFoo(); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// scoped_refptr<MyFoo> b; 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// b = a; 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// // now, |a| and |b| each own a reference to the same MyFoo object. 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// } 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <class T> 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class scoped_refptr { 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef T element_type; 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr() : ptr_(NULL) { 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr(T* p) : ptr_(p) { 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ptr_) 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ptr_->AddRef(); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr(const scoped_refptr<T>& r) : ptr_(r.ptr_) { 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ptr_) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ptr_->AddRef(); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <typename U> 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr(const scoped_refptr<U>& r) : ptr_(r.get()) { 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ptr_) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ptr_->AddRef(); 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~scoped_refptr() { 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ptr_) 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ptr_->Release(); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) T* get() const { return ptr_; } 2998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 3001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if !defined(DISABLE_SCOPED_REFPTR_CONVERSION_OPERATOR) 3018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Allow scoped_refptr<C> to be used in boolean expression 3028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // and comparison operations. 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) operator T*() const { return ptr_; } 3041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif 3051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci T& operator*() const { 3071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci assert(ptr_ != NULL); 3081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return *ptr_; 3091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 3108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) T* operator->() const { 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(ptr_ != NULL); 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ptr_; 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<T>& operator=(T* p) { 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // AddRef first so that self assignment should work 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (p) 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->AddRef(); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) T* old_ptr = ptr_; 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ptr_ = p; 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (old_ptr) 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) old_ptr->Release(); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return *this; 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<T>& operator=(const scoped_refptr<T>& r) { 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return *this = r.ptr_; 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template <typename U> 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<T>& operator=(const scoped_refptr<U>& r) { 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return *this = r.get(); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void swap(T** pp) { 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) T* p = ptr_; 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ptr_ = *pp; 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *pp = p; 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void swap(scoped_refptr<T>& r) { 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) swap(&r.ptr_); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(DISABLE_SCOPED_REFPTR_CONVERSION_OPERATOR) 3471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci template <typename U> 3481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool operator==(const scoped_refptr<U>& rhs) const { 3491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return ptr_ == rhs.get(); 3501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 3511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci template <typename U> 3531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool operator!=(const scoped_refptr<U>& rhs) const { 3541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return !operator==(rhs); 3551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 3561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci template <typename U> 3581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool operator<(const scoped_refptr<U>& rhs) const { 3591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return ptr_ < rhs.get(); 3601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 3611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif 3621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) T* ptr_; 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Handy utility for creating a scoped_refptr<T> out of a T* explicitly without 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// having to retype all the template arguments 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename T> 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<T> make_scoped_refptr(T* t) { 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return scoped_refptr<T>(t); 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(DISABLE_SCOPED_REFPTR_CONVERSION_OPERATOR) 3751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Temporary operator overloads to facilitate the transition... 3761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccitemplate <typename T, typename U> 3771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool operator==(const scoped_refptr<T>& lhs, const U* rhs) { 3781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return lhs.get() == rhs; 3791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 3801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccitemplate <typename T, typename U> 3821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool operator==(const T* lhs, const scoped_refptr<U>& rhs) { 3831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return lhs == rhs.get(); 3841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 3851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccitemplate <typename T, typename U> 3871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool operator!=(const scoped_refptr<T>& lhs, const U* rhs) { 3881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return !operator==(lhs, rhs); 3891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 3901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccitemplate <typename T, typename U> 3921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool operator!=(const T* lhs, const scoped_refptr<U>& rhs) { 3931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return !operator==(lhs, rhs); 3941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 3951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccitemplate <typename T> 3971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccistd::ostream& operator<<(std::ostream& out, const scoped_refptr<T>& p) { 3981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return out << p.get(); 3991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 4001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif // defined(DISABLE_SCOPED_REFPTR_CONVERSION_OPERATOR) 4011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // BASE_MEMORY_REF_COUNTED_H_ 403