Add R_8 GPU memory buffers format.
[chromium-blink-merge.git] / base / memory / ref_counted.h
blob219437ed8d82b8b35835a6c3297d5f719f14c277
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 namespace base {
22 namespace subtle {
24 class BASE_EXPORT RefCountedBase {
25 public:
26 bool HasOneRef() const { return ref_count_ == 1; }
28 protected:
29 RefCountedBase()
30 : ref_count_(0)
31 #ifndef NDEBUG
32 , in_dtor_(false)
33 #endif
37 ~RefCountedBase() {
38 #ifndef NDEBUG
39 DCHECK(in_dtor_) << "RefCounted object deleted without calling Release()";
40 #endif
44 void AddRef() const {
45 // TODO(maruel): Add back once it doesn't assert 500 times/sec.
46 // Current thread books the critical section "AddRelease"
47 // without release it.
48 // DFAKE_SCOPED_LOCK_THREAD_LOCKED(add_release_);
49 #ifndef NDEBUG
50 DCHECK(!in_dtor_);
51 #endif
52 ++ref_count_;
55 // Returns true if the object should self-delete.
56 bool Release() const {
57 // TODO(maruel): Add back once it doesn't assert 500 times/sec.
58 // Current thread books the critical section "AddRelease"
59 // without release it.
60 // DFAKE_SCOPED_LOCK_THREAD_LOCKED(add_release_);
61 #ifndef NDEBUG
62 DCHECK(!in_dtor_);
63 #endif
64 if (--ref_count_ == 0) {
65 #ifndef NDEBUG
66 in_dtor_ = true;
67 #endif
68 return true;
70 return false;
73 private:
74 mutable int ref_count_;
75 #ifndef NDEBUG
76 mutable bool in_dtor_;
77 #endif
79 DFAKE_MUTEX(add_release_);
81 DISALLOW_COPY_AND_ASSIGN(RefCountedBase);
84 class BASE_EXPORT RefCountedThreadSafeBase {
85 public:
86 bool HasOneRef() const;
88 protected:
89 RefCountedThreadSafeBase();
90 ~RefCountedThreadSafeBase();
92 void AddRef() const;
94 // Returns true if the object should self-delete.
95 bool Release() const;
97 private:
98 mutable AtomicRefCount ref_count_;
99 #ifndef NDEBUG
100 mutable bool in_dtor_;
101 #endif
103 DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafeBase);
106 } // namespace subtle
109 // A base class for reference counted classes. Otherwise, known as a cheap
110 // knock-off of WebKit's RefCounted<T> class. To use this guy just extend your
111 // class from it like so:
113 // class MyFoo : public base::RefCounted<MyFoo> {
114 // ...
115 // private:
116 // friend class base::RefCounted<MyFoo>;
117 // ~MyFoo();
118 // };
120 // You should always make your destructor private, to avoid any code deleting
121 // the object accidently while there are references to it.
122 template <class T>
123 class RefCounted : public subtle::RefCountedBase {
124 public:
125 RefCounted() {}
127 void AddRef() const {
128 subtle::RefCountedBase::AddRef();
131 void Release() const {
132 if (subtle::RefCountedBase::Release()) {
133 delete static_cast<const T*>(this);
137 protected:
138 ~RefCounted() {}
140 private:
141 DISALLOW_COPY_AND_ASSIGN(RefCounted<T>);
144 // Forward declaration.
145 template <class T, typename Traits> class RefCountedThreadSafe;
147 // Default traits for RefCountedThreadSafe<T>. Deletes the object when its ref
148 // count reaches 0. Overload to delete it on a different thread etc.
149 template<typename T>
150 struct DefaultRefCountedThreadSafeTraits {
151 static void Destruct(const T* x) {
152 // Delete through RefCountedThreadSafe to make child classes only need to be
153 // friend with RefCountedThreadSafe instead of this struct, which is an
154 // implementation detail.
155 RefCountedThreadSafe<T,
156 DefaultRefCountedThreadSafeTraits>::DeleteInternal(x);
161 // A thread-safe variant of RefCounted<T>
163 // class MyFoo : public base::RefCountedThreadSafe<MyFoo> {
164 // ...
165 // };
167 // If you're using the default trait, then you should add compile time
168 // asserts that no one else is deleting your object. i.e.
169 // private:
170 // friend class base::RefCountedThreadSafe<MyFoo>;
171 // ~MyFoo();
172 template <class T, typename Traits = DefaultRefCountedThreadSafeTraits<T> >
173 class RefCountedThreadSafe : public subtle::RefCountedThreadSafeBase {
174 public:
175 RefCountedThreadSafe() {}
177 void AddRef() const {
178 subtle::RefCountedThreadSafeBase::AddRef();
181 void Release() const {
182 if (subtle::RefCountedThreadSafeBase::Release()) {
183 Traits::Destruct(static_cast<const T*>(this));
187 protected:
188 ~RefCountedThreadSafe() {}
190 private:
191 friend struct DefaultRefCountedThreadSafeTraits<T>;
192 static void DeleteInternal(const T* x) { delete x; }
194 DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafe);
198 // A thread-safe wrapper for some piece of data so we can place other
199 // things in scoped_refptrs<>.
201 template<typename T>
202 class RefCountedData
203 : public base::RefCountedThreadSafe< base::RefCountedData<T> > {
204 public:
205 RefCountedData() : data() {}
206 RefCountedData(const T& in_value) : data(in_value) {}
208 T data;
210 private:
211 friend class base::RefCountedThreadSafe<base::RefCountedData<T> >;
212 ~RefCountedData() {}
215 } // namespace base
218 // A smart pointer class for reference counted objects. Use this class instead
219 // of calling AddRef and Release manually on a reference counted object to
220 // avoid common memory leaks caused by forgetting to Release an object
221 // reference. Sample usage:
223 // class MyFoo : public RefCounted<MyFoo> {
224 // ...
225 // };
227 // void some_function() {
228 // scoped_refptr<MyFoo> foo = new MyFoo();
229 // foo->Method(param);
230 // // |foo| is released when this function returns
231 // }
233 // void some_other_function() {
234 // scoped_refptr<MyFoo> foo = new MyFoo();
235 // ...
236 // foo = NULL; // explicitly releases |foo|
237 // ...
238 // if (foo)
239 // foo->Method(param);
240 // }
242 // The above examples show how scoped_refptr<T> acts like a pointer to T.
243 // Given two scoped_refptr<T> classes, it is also possible to exchange
244 // references between the two objects, like so:
246 // {
247 // scoped_refptr<MyFoo> a = new MyFoo();
248 // scoped_refptr<MyFoo> b;
250 // b.swap(a);
251 // // now, |b| references the MyFoo object, and |a| references NULL.
252 // }
254 // To make both |a| and |b| in the above example reference the same MyFoo
255 // object, simply use the assignment operator:
257 // {
258 // scoped_refptr<MyFoo> a = new MyFoo();
259 // scoped_refptr<MyFoo> b;
261 // b = a;
262 // // now, |a| and |b| each own a reference to the same MyFoo object.
263 // }
265 template <class T>
266 class scoped_refptr {
267 public:
268 typedef T element_type;
270 scoped_refptr() : ptr_(NULL) {
273 scoped_refptr(T* p) : ptr_(p) {
274 if (ptr_)
275 AddRef(ptr_);
278 scoped_refptr(const scoped_refptr<T>& r) : ptr_(r.ptr_) {
279 if (ptr_)
280 AddRef(ptr_);
283 template <typename U>
284 scoped_refptr(const scoped_refptr<U>& r) : ptr_(r.get()) {
285 if (ptr_)
286 AddRef(ptr_);
289 ~scoped_refptr() {
290 if (ptr_)
291 Release(ptr_);
294 T* get() const { return ptr_; }
296 T& operator*() const {
297 assert(ptr_ != NULL);
298 return *ptr_;
301 T* operator->() const {
302 assert(ptr_ != NULL);
303 return ptr_;
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;
317 scoped_refptr<T>& operator=(const scoped_refptr<T>& r) {
318 return *this = r.ptr_;
321 template <typename U>
322 scoped_refptr<T>& operator=(const scoped_refptr<U>& r) {
323 return *this = r.get();
326 void swap(T** pp) {
327 T* p = ptr_;
328 ptr_ = *pp;
329 *pp = p;
332 void swap(scoped_refptr<T>& r) {
333 swap(&r.ptr_);
336 private:
337 // Allow scoped_refptr<T> to be used in boolean expressions, but not
338 // implicitly convertible to a real bool (which is dangerous).
340 // Note that this trick is only safe when the == and != operators
341 // are declared explicitly, as otherwise "refptr1 == refptr2"
342 // will compile but do the wrong thing (i.e., convert to Testable
343 // and then do the comparison).
344 typedef T* scoped_refptr::*Testable;
346 public:
347 operator Testable() const { return ptr_ ? &scoped_refptr::ptr_ : nullptr; }
349 template <typename U>
350 bool operator==(const scoped_refptr<U>& rhs) const {
351 return ptr_ == rhs.get();
354 template <typename U>
355 bool operator!=(const scoped_refptr<U>& rhs) const {
356 return !operator==(rhs);
359 template <typename U>
360 bool operator<(const scoped_refptr<U>& rhs) const {
361 return ptr_ < rhs.get();
364 protected:
365 T* ptr_;
367 private:
368 // Non-inline helpers to allow:
369 // class Opaque;
370 // extern template class scoped_refptr<Opaque>;
371 // Otherwise the compiler will complain that Opaque is an incomplete type.
372 static void AddRef(T* ptr);
373 static void Release(T* ptr);
376 template <typename T>
377 void scoped_refptr<T>::AddRef(T* ptr) {
378 ptr->AddRef();
381 template <typename T>
382 void scoped_refptr<T>::Release(T* ptr) {
383 ptr->Release();
386 // Handy utility for creating a scoped_refptr<T> out of a T* explicitly without
387 // having to retype all the template arguments
388 template <typename T>
389 scoped_refptr<T> make_scoped_refptr(T* t) {
390 return scoped_refptr<T>(t);
393 // Temporary operator overloads to facilitate the transition. See
394 // https://crbug.com/110610.
395 template <typename T, typename U>
396 bool operator==(const scoped_refptr<T>& lhs, const U* rhs) {
397 return lhs.get() == rhs;
400 template <typename T, typename U>
401 bool operator==(const T* lhs, const scoped_refptr<U>& rhs) {
402 return lhs == rhs.get();
405 template <typename T, typename U>
406 bool operator!=(const scoped_refptr<T>& lhs, const U* rhs) {
407 return !operator==(lhs, rhs);
410 template <typename T, typename U>
411 bool operator!=(const T* lhs, const scoped_refptr<U>& rhs) {
412 return !operator==(lhs, rhs);
415 template <typename T>
416 std::ostream& operator<<(std::ostream& out, const scoped_refptr<T>& p) {
417 return out << p.get();
420 #endif // BASE_MEMORY_REF_COUNTED_H_