|
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 |
|
10 #include "base/atomic_ref_count.h" |
|
11 #include "base/base_export.h" |
|
12 #include "base/compiler_specific.h" |
|
13 #include "base/threading/thread_collision_warner.h" |
|
14 |
|
15 namespace base { |
|
16 |
|
17 namespace subtle { |
|
18 |
|
19 class BASE_EXPORT RefCountedBase { |
|
20 public: |
|
21 bool HasOneRef() const { return ref_count_ == 1; } |
|
22 |
|
23 protected: |
|
24 RefCountedBase(); |
|
25 ~RefCountedBase(); |
|
26 |
|
27 void AddRef() const; |
|
28 |
|
29 // Returns true if the object should self-delete. |
|
30 bool Release() const; |
|
31 |
|
32 private: |
|
33 mutable int ref_count_; |
|
34 #ifndef NDEBUG |
|
35 mutable bool in_dtor_; |
|
36 #endif |
|
37 |
|
38 DFAKE_MUTEX(add_release_); |
|
39 |
|
40 DISALLOW_COPY_AND_ASSIGN(RefCountedBase); |
|
41 }; |
|
42 |
|
43 class BASE_EXPORT RefCountedThreadSafeBase { |
|
44 public: |
|
45 bool HasOneRef() const; |
|
46 |
|
47 protected: |
|
48 RefCountedThreadSafeBase(); |
|
49 ~RefCountedThreadSafeBase(); |
|
50 |
|
51 void AddRef() const; |
|
52 |
|
53 // Returns true if the object should self-delete. |
|
54 bool Release() const; |
|
55 |
|
56 private: |
|
57 mutable AtomicRefCount ref_count_; |
|
58 #ifndef NDEBUG |
|
59 mutable bool in_dtor_; |
|
60 #endif |
|
61 |
|
62 DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafeBase); |
|
63 }; |
|
64 |
|
65 } // namespace subtle |
|
66 |
|
67 // |
|
68 // A base class for reference counted classes. Otherwise, known as a cheap |
|
69 // knock-off of WebKit's RefCounted<T> class. To use this guy just extend your |
|
70 // class from it like so: |
|
71 // |
|
72 // class MyFoo : public base::RefCounted<MyFoo> { |
|
73 // ... |
|
74 // private: |
|
75 // friend class base::RefCounted<MyFoo>; |
|
76 // ~MyFoo(); |
|
77 // }; |
|
78 // |
|
79 // You should always make your destructor private, to avoid any code deleting |
|
80 // the object accidently while there are references to it. |
|
81 template <class T> |
|
82 class RefCounted : public subtle::RefCountedBase { |
|
83 public: |
|
84 RefCounted() {} |
|
85 |
|
86 void AddRef() const { |
|
87 subtle::RefCountedBase::AddRef(); |
|
88 } |
|
89 |
|
90 void Release() const { |
|
91 if (subtle::RefCountedBase::Release()) { |
|
92 delete static_cast<const T*>(this); |
|
93 } |
|
94 } |
|
95 |
|
96 protected: |
|
97 ~RefCounted() {} |
|
98 |
|
99 private: |
|
100 DISALLOW_COPY_AND_ASSIGN(RefCounted<T>); |
|
101 }; |
|
102 |
|
103 // Forward declaration. |
|
104 template <class T, typename Traits> class RefCountedThreadSafe; |
|
105 |
|
106 // Default traits for RefCountedThreadSafe<T>. Deletes the object when its ref |
|
107 // count reaches 0. Overload to delete it on a different thread etc. |
|
108 template<typename T> |
|
109 struct DefaultRefCountedThreadSafeTraits { |
|
110 static void Destruct(const T* x) { |
|
111 // Delete through RefCountedThreadSafe to make child classes only need to be |
|
112 // friend with RefCountedThreadSafe instead of this struct, which is an |
|
113 // implementation detail. |
|
114 RefCountedThreadSafe<T, |
|
115 DefaultRefCountedThreadSafeTraits>::DeleteInternal(x); |
|
116 } |
|
117 }; |
|
118 |
|
119 // |
|
120 // A thread-safe variant of RefCounted<T> |
|
121 // |
|
122 // class MyFoo : public base::RefCountedThreadSafe<MyFoo> { |
|
123 // ... |
|
124 // }; |
|
125 // |
|
126 // If you're using the default trait, then you should add compile time |
|
127 // asserts that no one else is deleting your object. i.e. |
|
128 // private: |
|
129 // friend class base::RefCountedThreadSafe<MyFoo>; |
|
130 // ~MyFoo(); |
|
131 template <class T, typename Traits = DefaultRefCountedThreadSafeTraits<T> > |
|
132 class RefCountedThreadSafe : public subtle::RefCountedThreadSafeBase { |
|
133 public: |
|
134 RefCountedThreadSafe() {} |
|
135 |
|
136 void AddRef() const { |
|
137 subtle::RefCountedThreadSafeBase::AddRef(); |
|
138 } |
|
139 |
|
140 void Release() const { |
|
141 if (subtle::RefCountedThreadSafeBase::Release()) { |
|
142 Traits::Destruct(static_cast<const T*>(this)); |
|
143 } |
|
144 } |
|
145 |
|
146 protected: |
|
147 ~RefCountedThreadSafe() {} |
|
148 |
|
149 private: |
|
150 friend struct DefaultRefCountedThreadSafeTraits<T>; |
|
151 static void DeleteInternal(const T* x) { delete x; } |
|
152 |
|
153 DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafe); |
|
154 }; |
|
155 |
|
156 // |
|
157 // A thread-safe wrapper for some piece of data so we can place other |
|
158 // things in scoped_refptrs<>. |
|
159 // |
|
160 template<typename T> |
|
161 class RefCountedData |
|
162 : public base::RefCountedThreadSafe< base::RefCountedData<T> > { |
|
163 public: |
|
164 RefCountedData() : data() {} |
|
165 RefCountedData(const T& in_value) : data(in_value) {} |
|
166 |
|
167 T data; |
|
168 |
|
169 private: |
|
170 friend class base::RefCountedThreadSafe<base::RefCountedData<T> >; |
|
171 ~RefCountedData() {} |
|
172 }; |
|
173 |
|
174 } // namespace base |
|
175 |
|
176 // |
|
177 // A smart pointer class for reference counted objects. Use this class instead |
|
178 // of calling AddRef and Release manually on a reference counted object to |
|
179 // avoid common memory leaks caused by forgetting to Release an object |
|
180 // reference. Sample usage: |
|
181 // |
|
182 // class MyFoo : public RefCounted<MyFoo> { |
|
183 // ... |
|
184 // }; |
|
185 // |
|
186 // void some_function() { |
|
187 // scoped_refptr<MyFoo> foo = new MyFoo(); |
|
188 // foo->Method(param); |
|
189 // // |foo| is released when this function returns |
|
190 // } |
|
191 // |
|
192 // void some_other_function() { |
|
193 // scoped_refptr<MyFoo> foo = new MyFoo(); |
|
194 // ... |
|
195 // foo = NULL; // explicitly releases |foo| |
|
196 // ... |
|
197 // if (foo) |
|
198 // foo->Method(param); |
|
199 // } |
|
200 // |
|
201 // The above examples show how scoped_refptr<T> acts like a pointer to T. |
|
202 // Given two scoped_refptr<T> classes, it is also possible to exchange |
|
203 // references between the two objects, like so: |
|
204 // |
|
205 // { |
|
206 // scoped_refptr<MyFoo> a = new MyFoo(); |
|
207 // scoped_refptr<MyFoo> b; |
|
208 // |
|
209 // b.swap(a); |
|
210 // // now, |b| references the MyFoo object, and |a| references NULL. |
|
211 // } |
|
212 // |
|
213 // To make both |a| and |b| in the above example reference the same MyFoo |
|
214 // object, simply use the assignment operator: |
|
215 // |
|
216 // { |
|
217 // scoped_refptr<MyFoo> a = new MyFoo(); |
|
218 // scoped_refptr<MyFoo> b; |
|
219 // |
|
220 // b = a; |
|
221 // // now, |a| and |b| each own a reference to the same MyFoo object. |
|
222 // } |
|
223 // |
|
224 template <class T> |
|
225 class scoped_refptr { |
|
226 public: |
|
227 typedef T element_type; |
|
228 |
|
229 scoped_refptr() : ptr_(NULL) { |
|
230 } |
|
231 |
|
232 scoped_refptr(T* p) : ptr_(p) { |
|
233 if (ptr_) |
|
234 ptr_->AddRef(); |
|
235 } |
|
236 |
|
237 scoped_refptr(const scoped_refptr<T>& r) : ptr_(r.ptr_) { |
|
238 if (ptr_) |
|
239 ptr_->AddRef(); |
|
240 } |
|
241 |
|
242 template <typename U> |
|
243 scoped_refptr(const scoped_refptr<U>& r) : ptr_(r.get()) { |
|
244 if (ptr_) |
|
245 ptr_->AddRef(); |
|
246 } |
|
247 |
|
248 ~scoped_refptr() { |
|
249 if (ptr_) |
|
250 ptr_->Release(); |
|
251 } |
|
252 |
|
253 T* get() const { return ptr_; } |
|
254 operator T*() const { return ptr_; } |
|
255 T* operator->() const { |
|
256 assert(ptr_ != NULL); |
|
257 return ptr_; |
|
258 } |
|
259 |
|
260 scoped_refptr<T>& operator=(T* p) { |
|
261 // AddRef first so that self assignment should work |
|
262 if (p) |
|
263 p->AddRef(); |
|
264 T* old_ptr = ptr_; |
|
265 ptr_ = p; |
|
266 if (old_ptr) |
|
267 old_ptr->Release(); |
|
268 return *this; |
|
269 } |
|
270 |
|
271 scoped_refptr<T>& operator=(const scoped_refptr<T>& r) { |
|
272 return *this = r.ptr_; |
|
273 } |
|
274 |
|
275 template <typename U> |
|
276 scoped_refptr<T>& operator=(const scoped_refptr<U>& r) { |
|
277 return *this = r.get(); |
|
278 } |
|
279 |
|
280 void swap(T** pp) { |
|
281 T* p = ptr_; |
|
282 ptr_ = *pp; |
|
283 *pp = p; |
|
284 } |
|
285 |
|
286 void swap(scoped_refptr<T>& r) { |
|
287 swap(&r.ptr_); |
|
288 } |
|
289 |
|
290 protected: |
|
291 T* ptr_; |
|
292 }; |
|
293 |
|
294 // Handy utility for creating a scoped_refptr<T> out of a T* explicitly without |
|
295 // having to retype all the template arguments |
|
296 template <typename T> |
|
297 scoped_refptr<T> make_scoped_refptr(T* t) { |
|
298 return scoped_refptr<T>(t); |
|
299 } |
|
300 |
|
301 #endif // BASE_MEMORY_REF_COUNTED_H_ |