OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef BASE_REF_COUNTED_H_ | 5 #ifndef BASE_REF_COUNTED_H_ |
6 #define BASE_REF_COUNTED_H_ | 6 #define BASE_REF_COUNTED_H_ |
7 | 7 |
8 #include "base/atomic_ref_count.h" | 8 #include "base/atomic_ref_count.h" |
9 #include "base/thread_collision_warner.h" | 9 #include "base/thread_collision_warner.h" |
10 | 10 |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
86 void Release() { | 86 void Release() { |
87 if (subtle::RefCountedBase::Release()) { | 87 if (subtle::RefCountedBase::Release()) { |
88 delete static_cast<T*>(this); | 88 delete static_cast<T*>(this); |
89 } | 89 } |
90 } | 90 } |
91 | 91 |
92 private: | 92 private: |
93 DISALLOW_COPY_AND_ASSIGN(RefCounted<T>); | 93 DISALLOW_COPY_AND_ASSIGN(RefCounted<T>); |
94 }; | 94 }; |
95 | 95 |
| 96 // Forward declaration. |
| 97 template <class T, typename Traits> class RefCountedThreadSafe; |
| 98 |
| 99 // Default traits for RefCountedThreadSafe<T>. Deletes the object when its ref |
| 100 // count reaches 0. Overload to delete it on a different thread etc. |
| 101 template<typename T> |
| 102 struct DefaultRefCountedThreadSafeTraits { |
| 103 static void Destruct(T* x) { |
| 104 // Delete through RefCountedThreadSafe to make child classes only need to be |
| 105 // friend with RefCountedThreadSafe instead of this struct, which is an |
| 106 // implementation detail. |
| 107 RefCountedThreadSafe<T, DefaultRefCountedThreadSafeTraits>::DeleteInternal(x
); |
| 108 } |
| 109 }; |
| 110 |
96 // | 111 // |
97 // A thread-safe variant of RefCounted<T> | 112 // A thread-safe variant of RefCounted<T> |
98 // | 113 // |
99 // class MyFoo : public base::RefCountedThreadSafe<MyFoo> { | 114 // class MyFoo : public base::RefCountedThreadSafe<MyFoo> { |
100 // ... | 115 // ... |
101 // }; | 116 // }; |
102 // | 117 // |
103 template <class T> | 118 // If you're using the default trait, then you may choose to add compile time |
| 119 // asserts that no one else is deleting your object. i.e. |
| 120 // private: |
| 121 // friend struct base::RefCountedThreadSafe<MyFoo>; |
| 122 // ~MyFoo(); |
| 123 template <class T, typename Traits = DefaultRefCountedThreadSafeTraits<T> > |
104 class RefCountedThreadSafe : public subtle::RefCountedThreadSafeBase { | 124 class RefCountedThreadSafe : public subtle::RefCountedThreadSafeBase { |
105 public: | 125 public: |
106 RefCountedThreadSafe() { } | 126 RefCountedThreadSafe() { } |
107 ~RefCountedThreadSafe() { } | 127 ~RefCountedThreadSafe() { } |
108 | 128 |
109 void AddRef() { | 129 void AddRef() { |
110 subtle::RefCountedThreadSafeBase::AddRef(); | 130 subtle::RefCountedThreadSafeBase::AddRef(); |
111 } | 131 } |
112 | 132 |
113 void Release() { | 133 void Release() { |
114 if (subtle::RefCountedThreadSafeBase::Release()) { | 134 if (subtle::RefCountedThreadSafeBase::Release()) { |
115 delete static_cast<T*>(this); | 135 Traits::Destruct(static_cast<T*>(this)); |
116 } | 136 } |
117 } | 137 } |
118 | 138 |
119 private: | 139 private: |
120 DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafe<T>); | 140 friend struct DefaultRefCountedThreadSafeTraits<T>; |
| 141 static void DeleteInternal(T* x) { delete x; } |
| 142 |
| 143 DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafe); |
121 }; | 144 }; |
122 | 145 |
123 // | 146 // |
124 // A wrapper for some piece of data so we can place other things in | 147 // A wrapper for some piece of data so we can place other things in |
125 // scoped_refptrs<>. | 148 // scoped_refptrs<>. |
126 // | 149 // |
127 template<typename T> | 150 template<typename T> |
128 class RefCountedData : public base::RefCounted< base::RefCountedData<T> > { | 151 class RefCountedData : public base::RefCounted< base::RefCountedData<T> > { |
129 public: | 152 public: |
130 RefCountedData() : data() {} | 153 RefCountedData() : data() {} |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
241 | 264 |
242 void swap(scoped_refptr<T>& r) { | 265 void swap(scoped_refptr<T>& r) { |
243 swap(&r.ptr_); | 266 swap(&r.ptr_); |
244 } | 267 } |
245 | 268 |
246 protected: | 269 protected: |
247 T* ptr_; | 270 T* ptr_; |
248 }; | 271 }; |
249 | 272 |
250 #endif // BASE_REF_COUNTED_H_ | 273 #endif // BASE_REF_COUNTED_H_ |
OLD | NEW |