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