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.
5 #ifndef BASE_MEMORY_REF_COUNTED_H_
6 #define BASE_MEMORY_REF_COUNTED_H_
11 #include "base/atomic_ref_count.h"
12 #include "base/base_export.h"
13 #include "base/compiler_specific.h"
15 #include "base/logging.h"
17 #include "base/threading/thread_collision_warner.h"
18 #include "build/build_config.h"
24 class BASE_EXPORT RefCountedBase
{
26 bool HasOneRef() const { return ref_count_
== 1; }
39 DCHECK(in_dtor_
) << "RefCounted object deleted without calling Release()";
45 // TODO(maruel): Add back once it doesn't assert 500 times/sec.
46 // Current thread books the critical section "AddRelease"
47 // without release it.
48 // DFAKE_SCOPED_LOCK_THREAD_LOCKED(add_release_);
55 // Returns true if the object should self-delete.
56 bool Release() const {
57 // TODO(maruel): Add back once it doesn't assert 500 times/sec.
58 // Current thread books the critical section "AddRelease"
59 // without release it.
60 // DFAKE_SCOPED_LOCK_THREAD_LOCKED(add_release_);
64 if (--ref_count_
== 0) {
74 mutable int ref_count_
;
76 mutable bool in_dtor_
;
79 DFAKE_MUTEX(add_release_
);
81 DISALLOW_COPY_AND_ASSIGN(RefCountedBase
);
84 class BASE_EXPORT RefCountedThreadSafeBase
{
86 bool HasOneRef() const;
89 RefCountedThreadSafeBase();
90 ~RefCountedThreadSafeBase();
94 // Returns true if the object should self-delete.
98 mutable AtomicRefCount ref_count_
;
100 mutable bool in_dtor_
;
103 DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafeBase
);
106 } // namespace subtle
109 // A base class for reference counted classes. Otherwise, known as a cheap
110 // knock-off of WebKit's RefCounted<T> class. To use this guy just extend your
111 // class from it like so:
113 // class MyFoo : public base::RefCounted<MyFoo> {
116 // friend class base::RefCounted<MyFoo>;
120 // You should always make your destructor private, to avoid any code deleting
121 // the object accidently while there are references to it.
123 class RefCounted
: public subtle::RefCountedBase
{
127 void AddRef() const {
128 subtle::RefCountedBase::AddRef();
131 void Release() const {
132 if (subtle::RefCountedBase::Release()) {
133 delete static_cast<const T
*>(this);
141 DISALLOW_COPY_AND_ASSIGN(RefCounted
<T
>);
144 // Forward declaration.
145 template <class T
, typename Traits
> class RefCountedThreadSafe
;
147 // Default traits for RefCountedThreadSafe<T>. Deletes the object when its ref
148 // count reaches 0. Overload to delete it on a different thread etc.
150 struct DefaultRefCountedThreadSafeTraits
{
151 static void Destruct(const T
* x
) {
152 // Delete through RefCountedThreadSafe to make child classes only need to be
153 // friend with RefCountedThreadSafe instead of this struct, which is an
154 // implementation detail.
155 RefCountedThreadSafe
<T
,
156 DefaultRefCountedThreadSafeTraits
>::DeleteInternal(x
);
161 // A thread-safe variant of RefCounted<T>
163 // class MyFoo : public base::RefCountedThreadSafe<MyFoo> {
167 // If you're using the default trait, then you should add compile time
168 // asserts that no one else is deleting your object. i.e.
170 // friend class base::RefCountedThreadSafe<MyFoo>;
172 template <class T
, typename Traits
= DefaultRefCountedThreadSafeTraits
<T
> >
173 class RefCountedThreadSafe
: public subtle::RefCountedThreadSafeBase
{
175 RefCountedThreadSafe() {}
177 void AddRef() const {
178 subtle::RefCountedThreadSafeBase::AddRef();
181 void Release() const {
182 if (subtle::RefCountedThreadSafeBase::Release()) {
183 Traits::Destruct(static_cast<const T
*>(this));
188 ~RefCountedThreadSafe() {}
191 friend struct DefaultRefCountedThreadSafeTraits
<T
>;
192 static void DeleteInternal(const T
* x
) { delete x
; }
194 DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafe
);
198 // A thread-safe wrapper for some piece of data so we can place other
199 // things in scoped_refptrs<>.
203 : public base::RefCountedThreadSafe
< base::RefCountedData
<T
> > {
205 RefCountedData() : data() {}
206 RefCountedData(const T
& in_value
) : data(in_value
) {}
211 friend class base::RefCountedThreadSafe
<base::RefCountedData
<T
> >;
218 // A smart pointer class for reference counted objects. Use this class instead
219 // of calling AddRef and Release manually on a reference counted object to
220 // avoid common memory leaks caused by forgetting to Release an object
221 // reference. Sample usage:
223 // class MyFoo : public RefCounted<MyFoo> {
227 // void some_function() {
228 // scoped_refptr<MyFoo> foo = new MyFoo();
229 // foo->Method(param);
230 // // |foo| is released when this function returns
233 // void some_other_function() {
234 // scoped_refptr<MyFoo> foo = new MyFoo();
236 // foo = NULL; // explicitly releases |foo|
239 // foo->Method(param);
242 // The above examples show how scoped_refptr<T> acts like a pointer to T.
243 // Given two scoped_refptr<T> classes, it is also possible to exchange
244 // references between the two objects, like so:
247 // scoped_refptr<MyFoo> a = new MyFoo();
248 // scoped_refptr<MyFoo> b;
251 // // now, |b| references the MyFoo object, and |a| references NULL.
254 // To make both |a| and |b| in the above example reference the same MyFoo
255 // object, simply use the assignment operator:
258 // scoped_refptr<MyFoo> a = new MyFoo();
259 // scoped_refptr<MyFoo> b;
262 // // now, |a| and |b| each own a reference to the same MyFoo object.
266 class scoped_refptr
{
268 typedef T element_type
;
270 scoped_refptr() : ptr_(NULL
) {
273 scoped_refptr(T
* p
) : ptr_(p
) {
278 scoped_refptr(const scoped_refptr
<T
>& r
) : ptr_(r
.ptr_
) {
283 template <typename U
>
284 scoped_refptr(const scoped_refptr
<U
>& r
) : ptr_(r
.get()) {
294 T
* get() const { return ptr_
; }
296 T
& operator*() const {
297 assert(ptr_
!= NULL
);
301 T
* operator->() const {
302 assert(ptr_
!= NULL
);
306 scoped_refptr
<T
>& operator=(T
* p
) {
307 // AddRef first so that self assignment should work
317 scoped_refptr
<T
>& operator=(const scoped_refptr
<T
>& r
) {
318 return *this = r
.ptr_
;
321 template <typename U
>
322 scoped_refptr
<T
>& operator=(const scoped_refptr
<U
>& r
) {
323 return *this = r
.get();
332 void swap(scoped_refptr
<T
>& r
) {
337 // Allow scoped_refptr<T> to be used in boolean expressions, but not
338 // implicitly convertible to a real bool (which is dangerous).
340 // Note that this trick is only safe when the == and != operators
341 // are declared explicitly, as otherwise "refptr1 == refptr2"
342 // will compile but do the wrong thing (i.e., convert to Testable
343 // and then do the comparison).
344 typedef T
* scoped_refptr::*Testable
;
347 operator Testable() const { return ptr_
? &scoped_refptr::ptr_
: nullptr; }
349 template <typename U
>
350 bool operator==(const scoped_refptr
<U
>& rhs
) const {
351 return ptr_
== rhs
.get();
354 template <typename U
>
355 bool operator!=(const scoped_refptr
<U
>& rhs
) const {
356 return !operator==(rhs
);
359 template <typename U
>
360 bool operator<(const scoped_refptr
<U
>& rhs
) const {
361 return ptr_
< rhs
.get();
368 // Non-inline helpers to allow:
370 // extern template class scoped_refptr<Opaque>;
371 // Otherwise the compiler will complain that Opaque is an incomplete type.
372 static void AddRef(T
* ptr
);
373 static void Release(T
* ptr
);
376 template <typename T
>
377 void scoped_refptr
<T
>::AddRef(T
* ptr
) {
381 template <typename T
>
382 void scoped_refptr
<T
>::Release(T
* ptr
) {
386 // Handy utility for creating a scoped_refptr<T> out of a T* explicitly without
387 // having to retype all the template arguments
388 template <typename T
>
389 scoped_refptr
<T
> make_scoped_refptr(T
* t
) {
390 return scoped_refptr
<T
>(t
);
393 // Temporary operator overloads to facilitate the transition. See
394 // https://crbug.com/110610.
395 template <typename T
, typename U
>
396 bool operator==(const scoped_refptr
<T
>& lhs
, const U
* rhs
) {
397 return lhs
.get() == rhs
;
400 template <typename T
, typename U
>
401 bool operator==(const T
* lhs
, const scoped_refptr
<U
>& rhs
) {
402 return lhs
== rhs
.get();
405 template <typename T
, typename U
>
406 bool operator!=(const scoped_refptr
<T
>& lhs
, const U
* rhs
) {
407 return !operator==(lhs
, rhs
);
410 template <typename T
, typename U
>
411 bool operator!=(const T
* lhs
, const scoped_refptr
<U
>& rhs
) {
412 return !operator==(lhs
, rhs
);
415 template <typename T
>
416 std::ostream
& operator<<(std::ostream
& out
, const scoped_refptr
<T
>& p
) {
417 return out
<< p
.get();
420 #endif // BASE_MEMORY_REF_COUNTED_H_