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