NACL_WIN64 takes precedence over USE_OPENSSL.
[chromium-blink-merge.git] / base / memory / ref_counted.h
blob7869e72d11126cdc1492840b14c68b3a393de54a
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.
5 #ifndef BASE_MEMORY_REF_COUNTED_H_
6 #define BASE_MEMORY_REF_COUNTED_H_
8 #include <cassert>
9 #include <iosfwd>
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"
20 #if defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_IOS) || defined(OS_ANDROID)
21 #define DISABLE_SCOPED_REFPTR_CONVERSION_OPERATOR
22 #endif
24 namespace base {
26 namespace subtle {
28 class BASE_EXPORT RefCountedBase {
29 public:
30 bool HasOneRef() const { return ref_count_ == 1; }
32 protected:
33 RefCountedBase()
34 : ref_count_(0)
35 #ifndef NDEBUG
36 , in_dtor_(false)
37 #endif
41 ~RefCountedBase() {
42 #ifndef NDEBUG
43 DCHECK(in_dtor_) << "RefCounted object deleted without calling Release()";
44 #endif
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_;
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;
74 return false;
77 private:
78 mutable int ref_count_;
79 #ifndef NDEBUG
80 mutable bool in_dtor_;
81 #endif
83 DFAKE_MUTEX(add_release_);
85 DISALLOW_COPY_AND_ASSIGN(RefCountedBase);
88 class BASE_EXPORT RefCountedThreadSafeBase {
89 public:
90 bool HasOneRef() const;
92 protected:
93 RefCountedThreadSafeBase();
94 ~RefCountedThreadSafeBase();
96 void AddRef() const;
98 // Returns true if the object should self-delete.
99 bool Release() const;
101 private:
102 mutable AtomicRefCount ref_count_;
103 #ifndef NDEBUG
104 mutable bool in_dtor_;
105 #endif
107 DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafeBase);
110 } // namespace subtle
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:
117 // class MyFoo : public base::RefCounted<MyFoo> {
118 // ...
119 // private:
120 // friend class base::RefCounted<MyFoo>;
121 // ~MyFoo();
122 // };
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() {}
131 void AddRef() const {
132 subtle::RefCountedBase::AddRef();
135 void Release() const {
136 if (subtle::RefCountedBase::Release()) {
137 delete static_cast<const T*>(this);
141 protected:
142 ~RefCounted() {}
144 private:
145 DISALLOW_COPY_AND_ASSIGN(RefCounted<T>);
148 // Forward declaration.
149 template <class T, typename Traits> class RefCountedThreadSafe;
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);
165 // A thread-safe variant of RefCounted<T>
167 // class MyFoo : public base::RefCountedThreadSafe<MyFoo> {
168 // ...
169 // };
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() {}
181 void AddRef() const {
182 subtle::RefCountedThreadSafeBase::AddRef();
185 void Release() const {
186 if (subtle::RefCountedThreadSafeBase::Release()) {
187 Traits::Destruct(static_cast<const T*>(this));
191 protected:
192 ~RefCountedThreadSafe() {}
194 private:
195 friend struct DefaultRefCountedThreadSafeTraits<T>;
196 static void DeleteInternal(const T* x) { delete x; }
198 DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafe);
202 // A thread-safe wrapper for some piece of data so we can place other
203 // things in scoped_refptrs<>.
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) {}
212 T data;
214 private:
215 friend class base::RefCountedThreadSafe<base::RefCountedData<T> >;
216 ~RefCountedData() {}
219 } // namespace base
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:
227 // class MyFoo : public RefCounted<MyFoo> {
228 // ...
229 // };
231 // void some_function() {
232 // scoped_refptr<MyFoo> foo = new MyFoo();
233 // foo->Method(param);
234 // // |foo| is released when this function returns
235 // }
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 // }
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:
250 // {
251 // scoped_refptr<MyFoo> a = new MyFoo();
252 // scoped_refptr<MyFoo> b;
254 // b.swap(a);
255 // // now, |b| references the MyFoo object, and |a| references NULL.
256 // }
258 // To make both |a| and |b| in the above example reference the same MyFoo
259 // object, simply use the assignment operator:
261 // {
262 // scoped_refptr<MyFoo> a = new MyFoo();
263 // scoped_refptr<MyFoo> b;
265 // b = a;
266 // // now, |a| and |b| each own a reference to the same MyFoo object.
267 // }
269 template <class T>
270 class scoped_refptr {
271 public:
272 typedef T element_type;
274 scoped_refptr() : ptr_(NULL) {
277 scoped_refptr(T* p) : ptr_(p) {
278 if (ptr_)
279 AddRef(ptr_);
282 scoped_refptr(const scoped_refptr<T>& r) : ptr_(r.ptr_) {
283 if (ptr_)
284 AddRef(ptr_);
287 template <typename U>
288 scoped_refptr(const scoped_refptr<U>& r) : ptr_(r.get()) {
289 if (ptr_)
290 AddRef(ptr_);
293 ~scoped_refptr() {
294 if (ptr_)
295 Release(ptr_);
298 T* get() const { return ptr_; }
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
306 T& operator*() const {
307 assert(ptr_ != NULL);
308 return *ptr_;
311 T* operator->() const {
312 assert(ptr_ != NULL);
313 return ptr_;
316 scoped_refptr<T>& operator=(T* p) {
317 // AddRef first so that self assignment should work
318 if (p)
319 AddRef(p);
320 T* old_ptr = ptr_;
321 ptr_ = p;
322 if (old_ptr)
323 Release(old_ptr);
324 return *this;
327 scoped_refptr<T>& operator=(const scoped_refptr<T>& r) {
328 return *this = r.ptr_;
331 template <typename U>
332 scoped_refptr<T>& operator=(const scoped_refptr<U>& r) {
333 return *this = r.get();
336 void swap(T** pp) {
337 T* p = ptr_;
338 ptr_ = *pp;
339 *pp = p;
342 void swap(scoped_refptr<T>& r) {
343 swap(&r.ptr_);
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();
352 template <typename U>
353 bool operator!=(const scoped_refptr<U>& rhs) const {
354 return !operator==(rhs);
357 template <typename U>
358 bool operator<(const scoped_refptr<U>& rhs) const {
359 return ptr_ < rhs.get();
361 #endif
363 protected:
364 T* ptr_;
366 private:
367 // Non-inline helpers to allow:
368 // class Opaque;
369 // extern template class scoped_refptr<Opaque>;
370 // Otherwise the compiler will complain that Opaque is an incomplete type.
371 static void AddRef(T* ptr);
372 static void Release(T* ptr);
375 template <typename T>
376 void scoped_refptr<T>::AddRef(T* ptr) {
377 ptr->AddRef();
380 template <typename T>
381 void scoped_refptr<T>::Release(T* ptr) {
382 ptr->Release();
385 // Handy utility for creating a scoped_refptr<T> out of a T* explicitly without
386 // having to retype all the template arguments
387 template <typename T>
388 scoped_refptr<T> make_scoped_refptr(T* t) {
389 return scoped_refptr<T>(t);
392 #if defined(DISABLE_SCOPED_REFPTR_CONVERSION_OPERATOR)
393 // Temporary operator overloads to facilitate the transition...
394 template <typename T, typename U>
395 bool operator==(const scoped_refptr<T>& lhs, const U* rhs) {
396 return lhs.get() == rhs;
399 template <typename T, typename U>
400 bool operator==(const T* lhs, const scoped_refptr<U>& rhs) {
401 return lhs == rhs.get();
404 template <typename T, typename U>
405 bool operator!=(const scoped_refptr<T>& lhs, const U* rhs) {
406 return !operator==(lhs, rhs);
409 template <typename T, typename U>
410 bool operator!=(const T* lhs, const scoped_refptr<U>& rhs) {
411 return !operator==(lhs, rhs);
414 template <typename T>
415 std::ostream& operator<<(std::ostream& out, const scoped_refptr<T>& p) {
416 return out << p.get();
418 #endif // defined(DISABLE_SCOPED_REFPTR_CONVERSION_OPERATOR)
420 #endif // BASE_MEMORY_REF_COUNTED_H_