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_
10 #include "base/atomic_ref_count.h"
11 #include "base/base_export.h"
12 #include "base/compiler_specific.h"
14 #include "base/logging.h"
16 #include "base/threading/thread_collision_warner.h"
22 class BASE_EXPORT RefCountedBase
{
24 bool HasOneRef() const { return ref_count_
== 1; }
37 DCHECK(in_dtor_
) << "RefCounted object deleted without calling Release()";
43 // TODO(maruel): Add back once it doesn't assert 500 times/sec.
44 // Current thread books the critical section "AddRelease"
45 // without release it.
46 // DFAKE_SCOPED_LOCK_THREAD_LOCKED(add_release_);
53 // Returns true if the object should self-delete.
54 bool Release() const {
55 // TODO(maruel): Add back once it doesn't assert 500 times/sec.
56 // Current thread books the critical section "AddRelease"
57 // without release it.
58 // DFAKE_SCOPED_LOCK_THREAD_LOCKED(add_release_);
62 if (--ref_count_
== 0) {
72 mutable int ref_count_
;
74 mutable bool in_dtor_
;
77 DFAKE_MUTEX(add_release_
);
79 DISALLOW_COPY_AND_ASSIGN(RefCountedBase
);
82 class BASE_EXPORT RefCountedThreadSafeBase
{
84 bool HasOneRef() const;
87 RefCountedThreadSafeBase();
88 ~RefCountedThreadSafeBase();
92 // Returns true if the object should self-delete.
96 mutable AtomicRefCount ref_count_
;
98 mutable bool in_dtor_
;
101 DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafeBase
);
104 } // namespace subtle
107 // A base class for reference counted classes. Otherwise, known as a cheap
108 // knock-off of WebKit's RefCounted<T> class. To use this guy just extend your
109 // class from it like so:
111 // class MyFoo : public base::RefCounted<MyFoo> {
114 // friend class base::RefCounted<MyFoo>;
118 // You should always make your destructor private, to avoid any code deleting
119 // the object accidently while there are references to it.
121 class RefCounted
: public subtle::RefCountedBase
{
125 void AddRef() const {
126 subtle::RefCountedBase::AddRef();
129 void Release() const {
130 if (subtle::RefCountedBase::Release()) {
131 delete static_cast<const T
*>(this);
139 DISALLOW_COPY_AND_ASSIGN(RefCounted
<T
>);
142 // Forward declaration.
143 template <class T
, typename Traits
> class RefCountedThreadSafe
;
145 // Default traits for RefCountedThreadSafe<T>. Deletes the object when its ref
146 // count reaches 0. Overload to delete it on a different thread etc.
148 struct DefaultRefCountedThreadSafeTraits
{
149 static void Destruct(const T
* x
) {
150 // Delete through RefCountedThreadSafe to make child classes only need to be
151 // friend with RefCountedThreadSafe instead of this struct, which is an
152 // implementation detail.
153 RefCountedThreadSafe
<T
,
154 DefaultRefCountedThreadSafeTraits
>::DeleteInternal(x
);
159 // A thread-safe variant of RefCounted<T>
161 // class MyFoo : public base::RefCountedThreadSafe<MyFoo> {
165 // If you're using the default trait, then you should add compile time
166 // asserts that no one else is deleting your object. i.e.
168 // friend class base::RefCountedThreadSafe<MyFoo>;
170 template <class T
, typename Traits
= DefaultRefCountedThreadSafeTraits
<T
> >
171 class RefCountedThreadSafe
: public subtle::RefCountedThreadSafeBase
{
173 RefCountedThreadSafe() {}
175 void AddRef() const {
176 subtle::RefCountedThreadSafeBase::AddRef();
179 void Release() const {
180 if (subtle::RefCountedThreadSafeBase::Release()) {
181 Traits::Destruct(static_cast<const T
*>(this));
186 ~RefCountedThreadSafe() {}
189 friend struct DefaultRefCountedThreadSafeTraits
<T
>;
190 static void DeleteInternal(const T
* x
) { delete x
; }
192 DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafe
);
196 // A thread-safe wrapper for some piece of data so we can place other
197 // things in scoped_refptrs<>.
201 : public base::RefCountedThreadSafe
< base::RefCountedData
<T
> > {
203 RefCountedData() : data() {}
204 RefCountedData(const T
& in_value
) : data(in_value
) {}
209 friend class base::RefCountedThreadSafe
<base::RefCountedData
<T
> >;
216 // A smart pointer class for reference counted objects. Use this class instead
217 // of calling AddRef and Release manually on a reference counted object to
218 // avoid common memory leaks caused by forgetting to Release an object
219 // reference. Sample usage:
221 // class MyFoo : public RefCounted<MyFoo> {
225 // void some_function() {
226 // scoped_refptr<MyFoo> foo = new MyFoo();
227 // foo->Method(param);
228 // // |foo| is released when this function returns
231 // void some_other_function() {
232 // scoped_refptr<MyFoo> foo = new MyFoo();
234 // foo = NULL; // explicitly releases |foo|
237 // foo->Method(param);
240 // The above examples show how scoped_refptr<T> acts like a pointer to T.
241 // Given two scoped_refptr<T> classes, it is also possible to exchange
242 // references between the two objects, like so:
245 // scoped_refptr<MyFoo> a = new MyFoo();
246 // scoped_refptr<MyFoo> b;
249 // // now, |b| references the MyFoo object, and |a| references NULL.
252 // To make both |a| and |b| in the above example reference the same MyFoo
253 // object, simply use the assignment operator:
256 // scoped_refptr<MyFoo> a = new MyFoo();
257 // scoped_refptr<MyFoo> b;
260 // // now, |a| and |b| each own a reference to the same MyFoo object.
264 class scoped_refptr
{
266 typedef T element_type
;
268 scoped_refptr() : ptr_(NULL
) {
271 scoped_refptr(T
* p
) : ptr_(p
) {
276 scoped_refptr(const scoped_refptr
<T
>& r
) : ptr_(r
.ptr_
) {
281 template <typename U
>
282 scoped_refptr(const scoped_refptr
<U
>& r
) : ptr_(r
.get()) {
292 T
* get() const { return ptr_
; }
294 // Allow scoped_refptr<C> to be used in boolean expression
295 // and comparison operations.
296 operator T
*() const { return ptr_
; }
298 T
* operator->() const {
299 assert(ptr_
!= NULL
);
303 scoped_refptr
<T
>& operator=(T
* p
) {
304 // AddRef first so that self assignment should work
314 scoped_refptr
<T
>& operator=(const scoped_refptr
<T
>& r
) {
315 return *this = r
.ptr_
;
318 template <typename U
>
319 scoped_refptr
<T
>& operator=(const scoped_refptr
<U
>& r
) {
320 return *this = r
.get();
329 void swap(scoped_refptr
<T
>& r
) {
337 // Handy utility for creating a scoped_refptr<T> out of a T* explicitly without
338 // having to retype all the template arguments
339 template <typename T
>
340 scoped_refptr
<T
> make_scoped_refptr(T
* t
) {
341 return scoped_refptr
<T
>(t
);
344 #endif // BASE_MEMORY_REF_COUNTED_H_