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