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_