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 <atomic>
9 #include <cassert>
10 #include <iosfwd>
11 
12 #include "base/base_export.h"
13 #include "base/compiler_specific.h"
14 #include "base/macros.h"
15 #include "base/logging.h"
16 #include "build/build_config.h"
17 
18 namespace base {
19 
20 namespace subtle {
21 
22 class BASE_EXPORT RefCountedBase {
23  public:
HasOneRef()24   bool HasOneRef() const { return ref_count_ == 1; }
25 
26  protected:
RefCountedBase()27   RefCountedBase()
28       : ref_count_(0)
29   #ifndef NDEBUG
30       , in_dtor_(false)
31   #endif
32       {
33   }
34 
~RefCountedBase()35   ~RefCountedBase() {
36   #ifndef NDEBUG
37     DCHECK(in_dtor_) << "RefCounted object deleted without calling Release()";
38   #endif
39   }
40 
41 
AddRef()42   void AddRef() const {
43   #ifndef NDEBUG
44     DCHECK(!in_dtor_);
45   #endif
46     ++ref_count_;
47   }
48 
49   // Returns true if the object should self-delete.
Release()50   bool Release() const {
51   #ifndef NDEBUG
52     DCHECK(!in_dtor_);
53   #endif
54     if (--ref_count_ == 0) {
55   #ifndef NDEBUG
56       in_dtor_ = true;
57   #endif
58       return true;
59     }
60     return false;
61   }
62 
63  private:
64   mutable int ref_count_;
65 #ifndef NDEBUG
66   mutable bool in_dtor_;
67 #endif
68 
69   DISALLOW_COPY_AND_ASSIGN(RefCountedBase);
70 };
71 
72 class BASE_EXPORT RefCountedThreadSafeBase {
73  public:
74   bool HasOneRef() const;
75 
76  protected:
77   RefCountedThreadSafeBase();
78   ~RefCountedThreadSafeBase();
79 
80   void AddRef() const;
81 
82   // Returns true if the object should self-delete.
83   bool Release() const;
84 
85  private:
86   mutable std::atomic<int32_t> ref_count_;
87 #ifndef NDEBUG
88   mutable bool in_dtor_;
89 #endif
90 
91   DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafeBase);
92 };
93 
94 }  // namespace subtle
95 
96 //
97 // A base class for reference counted classes.  Otherwise, known as a cheap
98 // knock-off of WebKit's RefCounted<T> class.  To use this guy just extend your
99 // class from it like so:
100 //
101 //   class MyFoo : public base::RefCounted<MyFoo> {
102 //    ...
103 //    private:
104 //     friend class base::RefCounted<MyFoo>;
105 //     ~MyFoo();
106 //   };
107 //
108 // You should always make your destructor non-public, to avoid any code deleting
109 // the object accidently while there are references to it.
110 template <class T>
111 class RefCounted : public subtle::RefCountedBase {
112  public:
RefCounted()113   RefCounted() {}
114 
AddRef()115   void AddRef() const {
116     subtle::RefCountedBase::AddRef();
117   }
118 
Release()119   void Release() const {
120     if (subtle::RefCountedBase::Release()) {
121       delete static_cast<const T*>(this);
122     }
123   }
124 
125  protected:
~RefCounted()126   ~RefCounted() {}
127 
128  private:
129   DISALLOW_COPY_AND_ASSIGN(RefCounted<T>);
130 };
131 
132 // Forward declaration.
133 template <class T, typename Traits> class RefCountedThreadSafe;
134 
135 // Default traits for RefCountedThreadSafe<T>.  Deletes the object when its ref
136 // count reaches 0.  Overload to delete it on a different thread etc.
137 template<typename T>
138 struct DefaultRefCountedThreadSafeTraits {
DestructDefaultRefCountedThreadSafeTraits139   static void Destruct(const T* x) {
140     // Delete through RefCountedThreadSafe to make child classes only need to be
141     // friend with RefCountedThreadSafe instead of this struct, which is an
142     // implementation detail.
143     RefCountedThreadSafe<T,
144                          DefaultRefCountedThreadSafeTraits>::DeleteInternal(x);
145   }
146 };
147 
148 //
149 // A thread-safe variant of RefCounted<T>
150 //
151 //   class MyFoo : public base::RefCountedThreadSafe<MyFoo> {
152 //    ...
153 //   };
154 //
155 // If you're using the default trait, then you should add compile time
156 // asserts that no one else is deleting your object.  i.e.
157 //    private:
158 //     friend class base::RefCountedThreadSafe<MyFoo>;
159 //     ~MyFoo();
160 template <class T, typename Traits = DefaultRefCountedThreadSafeTraits<T> >
161 class RefCountedThreadSafe : public subtle::RefCountedThreadSafeBase {
162  public:
RefCountedThreadSafe()163   RefCountedThreadSafe() {}
164 
AddRef()165   void AddRef() const {
166     subtle::RefCountedThreadSafeBase::AddRef();
167   }
168 
Release()169   void Release() const {
170     if (subtle::RefCountedThreadSafeBase::Release()) {
171       Traits::Destruct(static_cast<const T*>(this));
172     }
173   }
174 
175  protected:
~RefCountedThreadSafe()176   ~RefCountedThreadSafe() {}
177 
178  private:
179   friend struct DefaultRefCountedThreadSafeTraits<T>;
180   static void DeleteInternal(const T* x) { delete x; }
181 
182   DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafe);
183 };
184 
185 //
186 // A thread-safe wrapper for some piece of data so we can place other
187 // things in scoped_refptrs<>.
188 //
189 template<typename T>
190 class RefCountedData
191     : public base::RefCountedThreadSafe< base::RefCountedData<T> > {
192  public:
193   RefCountedData() : data() {}
194   RefCountedData(const T& in_value) : data(in_value) {}
195 
196   T data;
197 
198  private:
199   friend class base::RefCountedThreadSafe<base::RefCountedData<T> >;
200   ~RefCountedData() {}
201 };
202 
203 }  // namespace base
204 
205 //
206 // A smart pointer class for reference counted objects.  Use this class instead
207 // of calling AddRef and Release manually on a reference counted object to
208 // avoid common memory leaks caused by forgetting to Release an object
209 // reference.  Sample usage:
210 //
211 //   class MyFoo : public RefCounted<MyFoo> {
212 //    ...
213 //   };
214 //
215 //   void some_function() {
216 //     scoped_refptr<MyFoo> foo = new MyFoo();
217 //     foo->Method(param);
218 //     // |foo| is released when this function returns
219 //   }
220 //
221 //   void some_other_function() {
222 //     scoped_refptr<MyFoo> foo = new MyFoo();
223 //     ...
224 //     foo = NULL;  // explicitly releases |foo|
225 //     ...
226 //     if (foo)
227 //       foo->Method(param);
228 //   }
229 //
230 // The above examples show how scoped_refptr<T> acts like a pointer to T.
231 // Given two scoped_refptr<T> classes, it is also possible to exchange
232 // references between the two objects, like so:
233 //
234 //   {
235 //     scoped_refptr<MyFoo> a = new MyFoo();
236 //     scoped_refptr<MyFoo> b;
237 //
238 //     b.swap(a);
239 //     // now, |b| references the MyFoo object, and |a| references NULL.
240 //   }
241 //
242 // To make both |a| and |b| in the above example reference the same MyFoo
243 // object, simply use the assignment operator:
244 //
245 //   {
246 //     scoped_refptr<MyFoo> a = new MyFoo();
247 //     scoped_refptr<MyFoo> b;
248 //
249 //     b = a;
250 //     // now, |a| and |b| each own a reference to the same MyFoo object.
251 //   }
252 //
253 template <class T>
254 class scoped_refptr {
255  public:
256   typedef T element_type;
257 
258   scoped_refptr() : ptr_(NULL) {
259   }
260 
261   scoped_refptr(T* p) : ptr_(p) {
262     if (ptr_)
263       AddRef(ptr_);
264   }
265 
266   // Copy constructor.
267   scoped_refptr(const scoped_refptr<T>& r) : ptr_(r.ptr_) {
268     if (ptr_)
269       AddRef(ptr_);
270   }
271 
272   // Copy conversion constructor.
273   template <typename U>
274   scoped_refptr(const scoped_refptr<U>& r) : ptr_(r.get()) {
275     if (ptr_)
276       AddRef(ptr_);
277   }
278 
279   // Move constructor. This is required in addition to the conversion
280   // constructor below in order for clang to warn about pessimizing moves.
281   scoped_refptr(scoped_refptr&& r) : ptr_(r.get()) { r.ptr_ = nullptr; }
282 
283   // Move conversion constructor.
284   template <typename U>
285   scoped_refptr(scoped_refptr<U>&& r) : ptr_(r.get()) {
286     r.ptr_ = nullptr;
287   }
288 
289   ~scoped_refptr() {
290     if (ptr_)
291       Release(ptr_);
292   }
293 
294   T* get() const { return ptr_; }
295 
296   T& operator*() const {
297     assert(ptr_ != NULL);
298     return *ptr_;
299   }
300 
301   T* operator->() const {
302     assert(ptr_ != NULL);
303     return ptr_;
304   }
305 
306   scoped_refptr<T>& operator=(T* p) {
307     // AddRef first so that self assignment should work
308     if (p)
309       AddRef(p);
310     T* old_ptr = ptr_;
311     ptr_ = p;
312     if (old_ptr)
313       Release(old_ptr);
314     return *this;
315   }
316 
317   scoped_refptr<T>& operator=(const scoped_refptr<T>& r) {
318     return *this = r.ptr_;
319   }
320 
321   template <typename U>
322   scoped_refptr<T>& operator=(const scoped_refptr<U>& r) {
323     return *this = r.get();
324   }
325 
326   scoped_refptr<T>& operator=(scoped_refptr<T>&& r) {
327     scoped_refptr<T>(std::move(r)).swap(*this);
328     return *this;
329   }
330 
331   template <typename U>
332   scoped_refptr<T>& operator=(scoped_refptr<U>&& r) {
333     scoped_refptr<T>(std::move(r)).swap(*this);
334     return *this;
335   }
336 
337   void swap(T** pp) {
338     T* p = ptr_;
339     ptr_ = *pp;
340     *pp = p;
341   }
342 
343   void swap(scoped_refptr<T>& r) {
344     swap(&r.ptr_);
345   }
346 
347  private:
348   template <typename U> friend class scoped_refptr;
349 
350   // Allow scoped_refptr<T> to be used in boolean expressions, but not
351   // implicitly convertible to a real bool (which is dangerous).
352   //
353   // Note that this trick is only safe when the == and != operators
354   // are declared explicitly, as otherwise "refptr1 == refptr2"
355   // will compile but do the wrong thing (i.e., convert to Testable
356   // and then do the comparison).
357   typedef T* scoped_refptr::*Testable;
358 
359  public:
360   operator Testable() const { return ptr_ ? &scoped_refptr::ptr_ : nullptr; }
361 
362   template <typename U>
363   bool operator==(const scoped_refptr<U>& rhs) const {
364     return ptr_ == rhs.get();
365   }
366 
367   template <typename U>
368   bool operator!=(const scoped_refptr<U>& rhs) const {
369     return !operator==(rhs);
370   }
371 
372   template <typename U>
373   bool operator<(const scoped_refptr<U>& rhs) const {
374     return ptr_ < rhs.get();
375   }
376 
377  protected:
378   T* ptr_;
379 
380  private:
381   // Non-inline helpers to allow:
382   //     class Opaque;
383   //     extern template class scoped_refptr<Opaque>;
384   // Otherwise the compiler will complain that Opaque is an incomplete type.
385   static void AddRef(T* ptr);
386   static void Release(T* ptr);
387 };
388 
389 template <typename T>
390 void scoped_refptr<T>::AddRef(T* ptr) {
391   ptr->AddRef();
392 }
393 
394 template <typename T>
395 void scoped_refptr<T>::Release(T* ptr) {
396   ptr->Release();
397 }
398 
399 // Handy utility for creating a scoped_refptr<T> out of a T* explicitly without
400 // having to retype all the template arguments
401 template <typename T>
402 scoped_refptr<T> make_scoped_refptr(T* t) {
403   return scoped_refptr<T>(t);
404 }
405 
406 // Temporary operator overloads to facilitate the transition. See
407 // https://crbug.com/110610.
408 template <typename T, typename U>
409 bool operator==(const scoped_refptr<T>& lhs, const U* rhs) {
410   return lhs.get() == rhs;
411 }
412 
413 template <typename T, typename U>
414 bool operator==(const T* lhs, const scoped_refptr<U>& rhs) {
415   return lhs == rhs.get();
416 }
417 
418 template <typename T, typename U>
419 bool operator!=(const scoped_refptr<T>& lhs, const U* rhs) {
420   return !operator==(lhs, rhs);
421 }
422 
423 template <typename T, typename U>
424 bool operator!=(const T* lhs, const scoped_refptr<U>& rhs) {
425   return !operator==(lhs, rhs);
426 }
427 
428 template <typename T>
429 std::ostream& operator<<(std::ostream& out, const scoped_refptr<T>& p) {
430   return out << p.get();
431 }
432 
433 #endif  // BASE_MEMORY_REF_COUNTED_H_
434