ref_counted.h revision c2cbc7df84951541b29200c3a6ade3163fb815ae
1// Copyright (c) 2011 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#pragma once
8
9#include "base/atomic_ref_count.h"
10#include "base/base_api.h"
11#include "base/threading/thread_collision_warner.h"
12
13namespace base {
14
15namespace subtle {
16
17class BASE_API RefCountedBase {
18 public:
19  static bool ImplementsThreadSafeReferenceCounting() { return false; }
20
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_API RefCountedThreadSafeBase {
44 public:
45  static bool ImplementsThreadSafeReferenceCounting() { return true; }
46
47  bool HasOneRef() const;
48
49 protected:
50  RefCountedThreadSafeBase();
51  ~RefCountedThreadSafeBase();
52
53  void AddRef() const;
54
55  // Returns true if the object should self-delete.
56  bool Release() const;
57
58 private:
59  mutable AtomicRefCount ref_count_;
60#ifndef NDEBUG
61  mutable bool in_dtor_;
62#endif
63
64  DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafeBase);
65};
66
67}  // namespace subtle
68
69//
70// A base class for reference counted classes.  Otherwise, known as a cheap
71// knock-off of WebKit's RefCounted<T> class.  To use this guy just extend your
72// class from it like so:
73//
74//   class MyFoo : public base::RefCounted<MyFoo> {
75//    ...
76//    private:
77//     friend class base::RefCounted<MyFoo>;
78//     ~MyFoo();
79//   };
80//
81// You should always make your destructor private, to avoid any code deleting
82// the object accidently while there are references to it.
83template <class T>
84class RefCounted : public subtle::RefCountedBase {
85 public:
86  RefCounted() { }
87  ~RefCounted() { }
88
89  void AddRef() const {
90    subtle::RefCountedBase::AddRef();
91  }
92
93  void Release() const {
94    if (subtle::RefCountedBase::Release()) {
95      delete static_cast<const T*>(this);
96    }
97  }
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  ~RefCountedThreadSafe() { }
136
137  void AddRef() const {
138    subtle::RefCountedThreadSafeBase::AddRef();
139  }
140
141  void Release() const {
142    if (subtle::RefCountedThreadSafeBase::Release()) {
143      Traits::Destruct(static_cast<const T*>(this));
144    }
145  }
146
147 private:
148  friend struct DefaultRefCountedThreadSafeTraits<T>;
149  static void DeleteInternal(const T* x) { delete x; }
150
151  DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafe);
152};
153
154//
155// A wrapper for some piece of data so we can place other things in
156// scoped_refptrs<>.
157//
158template<typename T>
159class RefCountedData : public base::RefCounted< base::RefCountedData<T> > {
160 public:
161  RefCountedData() : data() {}
162  RefCountedData(const T& in_value) : data(in_value) {}
163
164  T data;
165};
166
167}  // namespace base
168
169//
170// A smart pointer class for reference counted objects.  Use this class instead
171// of calling AddRef and Release manually on a reference counted object to
172// avoid common memory leaks caused by forgetting to Release an object
173// reference.  Sample usage:
174//
175//   class MyFoo : public RefCounted<MyFoo> {
176//    ...
177//   };
178//
179//   void some_function() {
180//     scoped_refptr<MyFoo> foo = new MyFoo();
181//     foo->Method(param);
182//     // |foo| is released when this function returns
183//   }
184//
185//   void some_other_function() {
186//     scoped_refptr<MyFoo> foo = new MyFoo();
187//     ...
188//     foo = NULL;  // explicitly releases |foo|
189//     ...
190//     if (foo)
191//       foo->Method(param);
192//   }
193//
194// The above examples show how scoped_refptr<T> acts like a pointer to T.
195// Given two scoped_refptr<T> classes, it is also possible to exchange
196// references between the two objects, like so:
197//
198//   {
199//     scoped_refptr<MyFoo> a = new MyFoo();
200//     scoped_refptr<MyFoo> b;
201//
202//     b.swap(a);
203//     // now, |b| references the MyFoo object, and |a| references NULL.
204//   }
205//
206// To make both |a| and |b| in the above example reference the same MyFoo
207// object, simply use the assignment operator:
208//
209//   {
210//     scoped_refptr<MyFoo> a = new MyFoo();
211//     scoped_refptr<MyFoo> b;
212//
213//     b = a;
214//     // now, |a| and |b| each own a reference to the same MyFoo object.
215//   }
216//
217template <class T>
218class scoped_refptr {
219 public:
220  scoped_refptr() : ptr_(NULL) {
221  }
222
223  scoped_refptr(T* p) : ptr_(p) {
224    if (ptr_)
225      ptr_->AddRef();
226  }
227
228  scoped_refptr(const scoped_refptr<T>& r) : ptr_(r.ptr_) {
229    if (ptr_)
230      ptr_->AddRef();
231  }
232
233  template <typename U>
234  scoped_refptr(const scoped_refptr<U>& r) : ptr_(r.get()) {
235    if (ptr_)
236      ptr_->AddRef();
237  }
238
239  ~scoped_refptr() {
240    if (ptr_)
241      ptr_->Release();
242  }
243
244  T* get() const { return ptr_; }
245  operator T*() const { return ptr_; }
246  T* operator->() const { return ptr_; }
247
248  // Release a pointer.
249  // The return value is the current pointer held by this object.
250  // If this object holds a NULL pointer, the return value is NULL.
251  // After this operation, this object will hold a NULL pointer,
252  // and will not own the object any more.
253  T* release() {
254    T* retVal = ptr_;
255    ptr_ = NULL;
256    return retVal;
257  }
258
259  scoped_refptr<T>& operator=(T* p) {
260    // AddRef first so that self assignment should work
261    if (p)
262      p->AddRef();
263    T* old_ptr = ptr_;
264    ptr_ = p;
265    if (old_ptr)
266      old_ptr ->Release();
267    return *this;
268  }
269
270  scoped_refptr<T>& operator=(const scoped_refptr<T>& r) {
271    return *this = r.ptr_;
272  }
273
274  template <typename U>
275  scoped_refptr<T>& operator=(const scoped_refptr<U>& r) {
276    return *this = r.get();
277  }
278
279  void swap(T** pp) {
280    T* p = ptr_;
281    ptr_ = *pp;
282    *pp = p;
283  }
284
285  void swap(scoped_refptr<T>& r) {
286    swap(&r.ptr_);
287  }
288
289 protected:
290  T* ptr_;
291};
292
293// Handy utility for creating a scoped_refptr<T> out of a T* explicitly without
294// having to retype all the template arguments
295template <typename T>
296scoped_refptr<T> make_scoped_refptr(T* t) {
297  return scoped_refptr<T>(t);
298}
299
300#endif  // BASE_MEMORY_REF_COUNTED_H_
301