ref_counted.h revision 5821806d5e7f356e8fa4b058a389a808ea183019
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.
4
5#ifndef BASE_MEMORY_REF_COUNTED_H_
6#define BASE_MEMORY_REF_COUNTED_H_
7
8#include <cassert>
9
10#include "base/atomic_ref_count.h"
11#include "base/base_export.h"
12#include "base/compiler_specific.h"
13#include "base/threading/thread_collision_warner.h"
14
15namespace base {
16
17namespace subtle {
18
19class BASE_EXPORT RefCountedBase {
20 public:
21  bool HasOneRef() const { return ref_count_ == 1; }
22
23 protected:
24  RefCountedBase();
25  ~RefCountedBase();
26
27  void AddRef() const;
28
29  // Returns true if the object should self-delete.
30  bool Release() const;
31
32 private:
33  mutable int ref_count_;
34#ifndef NDEBUG
35  mutable bool in_dtor_;
36#endif
37
38  DFAKE_MUTEX(add_release_);
39
40  DISALLOW_COPY_AND_ASSIGN(RefCountedBase);
41};
42
43class BASE_EXPORT RefCountedThreadSafeBase {
44 public:
45  bool HasOneRef() const;
46
47 protected:
48  RefCountedThreadSafeBase();
49  ~RefCountedThreadSafeBase();
50
51  void AddRef() const;
52
53  // Returns true if the object should self-delete.
54  bool Release() const;
55
56 private:
57  mutable AtomicRefCount ref_count_;
58#ifndef NDEBUG
59  mutable bool in_dtor_;
60#endif
61
62  DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafeBase);
63};
64
65}  // namespace subtle
66
67//
68// A base class for reference counted classes.  Otherwise, known as a cheap
69// knock-off of WebKit's RefCounted<T> class.  To use this guy just extend your
70// class from it like so:
71//
72//   class MyFoo : public base::RefCounted<MyFoo> {
73//    ...
74//    private:
75//     friend class base::RefCounted<MyFoo>;
76//     ~MyFoo();
77//   };
78//
79// You should always make your destructor private, to avoid any code deleting
80// the object accidently while there are references to it.
81template <class T>
82class RefCounted : public subtle::RefCountedBase {
83 public:
84  RefCounted() {}
85
86  void AddRef() const {
87    subtle::RefCountedBase::AddRef();
88  }
89
90  void Release() const {
91    if (subtle::RefCountedBase::Release()) {
92      delete static_cast<const T*>(this);
93    }
94  }
95
96 protected:
97  ~RefCounted() {}
98
99 private:
100  DISALLOW_COPY_AND_ASSIGN(RefCounted<T>);
101};
102
103// Forward declaration.
104template <class T, typename Traits> class RefCountedThreadSafe;
105
106// Default traits for RefCountedThreadSafe<T>.  Deletes the object when its ref
107// count reaches 0.  Overload to delete it on a different thread etc.
108template<typename T>
109struct DefaultRefCountedThreadSafeTraits {
110  static void Destruct(const T* x) {
111    // Delete through RefCountedThreadSafe to make child classes only need to be
112    // friend with RefCountedThreadSafe instead of this struct, which is an
113    // implementation detail.
114    RefCountedThreadSafe<T,
115                         DefaultRefCountedThreadSafeTraits>::DeleteInternal(x);
116  }
117};
118
119//
120// A thread-safe variant of RefCounted<T>
121//
122//   class MyFoo : public base::RefCountedThreadSafe<MyFoo> {
123//    ...
124//   };
125//
126// If you're using the default trait, then you should add compile time
127// asserts that no one else is deleting your object.  i.e.
128//    private:
129//     friend class base::RefCountedThreadSafe<MyFoo>;
130//     ~MyFoo();
131template <class T, typename Traits = DefaultRefCountedThreadSafeTraits<T> >
132class RefCountedThreadSafe : public subtle::RefCountedThreadSafeBase {
133 public:
134  RefCountedThreadSafe() {}
135
136  void AddRef() const {
137    subtle::RefCountedThreadSafeBase::AddRef();
138  }
139
140  void Release() const {
141    if (subtle::RefCountedThreadSafeBase::Release()) {
142      Traits::Destruct(static_cast<const T*>(this));
143    }
144  }
145
146 protected:
147  ~RefCountedThreadSafe() {}
148
149 private:
150  friend struct DefaultRefCountedThreadSafeTraits<T>;
151  static void DeleteInternal(const T* x) { delete x; }
152
153  DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafe);
154};
155
156//
157// A wrapper for some piece of data so we can place other things in
158// scoped_refptrs<>.
159//
160template<typename T>
161class RefCountedData : public base::RefCounted< base::RefCountedData<T> > {
162 public:
163  RefCountedData() : data() {}
164  RefCountedData(const T& in_value) : data(in_value) {}
165
166  T data;
167
168 private:
169  friend class base::RefCounted<base::RefCountedData<T> >;
170  ~RefCountedData() {}
171};
172
173}  // namespace base
174
175//
176// A smart pointer class for reference counted objects.  Use this class instead
177// of calling AddRef and Release manually on a reference counted object to
178// avoid common memory leaks caused by forgetting to Release an object
179// reference.  Sample usage:
180//
181//   class MyFoo : public RefCounted<MyFoo> {
182//    ...
183//   };
184//
185//   void some_function() {
186//     scoped_refptr<MyFoo> foo = new MyFoo();
187//     foo->Method(param);
188//     // |foo| is released when this function returns
189//   }
190//
191//   void some_other_function() {
192//     scoped_refptr<MyFoo> foo = new MyFoo();
193//     ...
194//     foo = NULL;  // explicitly releases |foo|
195//     ...
196//     if (foo)
197//       foo->Method(param);
198//   }
199//
200// The above examples show how scoped_refptr<T> acts like a pointer to T.
201// Given two scoped_refptr<T> classes, it is also possible to exchange
202// references between the two objects, like so:
203//
204//   {
205//     scoped_refptr<MyFoo> a = new MyFoo();
206//     scoped_refptr<MyFoo> b;
207//
208//     b.swap(a);
209//     // now, |b| references the MyFoo object, and |a| references NULL.
210//   }
211//
212// To make both |a| and |b| in the above example reference the same MyFoo
213// object, simply use the assignment operator:
214//
215//   {
216//     scoped_refptr<MyFoo> a = new MyFoo();
217//     scoped_refptr<MyFoo> b;
218//
219//     b = a;
220//     // now, |a| and |b| each own a reference to the same MyFoo object.
221//   }
222//
223template <class T>
224class scoped_refptr {
225 public:
226  typedef T element_type;
227
228  scoped_refptr() : ptr_(NULL) {
229  }
230
231  scoped_refptr(T* p) : ptr_(p) {
232    if (ptr_)
233      ptr_->AddRef();
234  }
235
236  scoped_refptr(const scoped_refptr<T>& r) : ptr_(r.ptr_) {
237    if (ptr_)
238      ptr_->AddRef();
239  }
240
241  template <typename U>
242  scoped_refptr(const scoped_refptr<U>& r) : ptr_(r.get()) {
243    if (ptr_)
244      ptr_->AddRef();
245  }
246
247  ~scoped_refptr() {
248    if (ptr_)
249      ptr_->Release();
250  }
251
252  T* get() const { return ptr_; }
253  operator T*() const { return ptr_; }
254  T* operator->() const {
255    assert(ptr_ != NULL);
256    return ptr_;
257  }
258
259  // Release a pointer.
260  // The return value is the current pointer held by this object.
261  // If this object holds a NULL pointer, the return value is NULL.
262  // After this operation, this object will hold a NULL pointer,
263  // and will not own the object any more.
264  T* release() WARN_UNUSED_RESULT {
265    T* retVal = ptr_;
266    ptr_ = NULL;
267    return retVal;
268  }
269
270  scoped_refptr<T>& operator=(T* p) {
271    // AddRef first so that self assignment should work
272    if (p)
273      p->AddRef();
274    T* old_ptr = ptr_;
275    ptr_ = p;
276    if (old_ptr)
277      old_ptr->Release();
278    return *this;
279  }
280
281  scoped_refptr<T>& operator=(const scoped_refptr<T>& r) {
282    return *this = r.ptr_;
283  }
284
285  template <typename U>
286  scoped_refptr<T>& operator=(const scoped_refptr<U>& r) {
287    return *this = r.get();
288  }
289
290  void swap(T** pp) {
291    T* p = ptr_;
292    ptr_ = *pp;
293    *pp = p;
294  }
295
296  void swap(scoped_refptr<T>& r) {
297    swap(&r.ptr_);
298  }
299
300 protected:
301  T* ptr_;
302};
303
304// Handy utility for creating a scoped_refptr<T> out of a T* explicitly without
305// having to retype all the template arguments
306template <typename T>
307scoped_refptr<T> make_scoped_refptr(T* t) {
308  return scoped_refptr<T>(t);
309}
310
311#endif  // BASE_MEMORY_REF_COUNTED_H_
312