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
3 : // found in the LICENSE file.
4 :
5 : #ifndef BASE_REF_COUNTED_H_
6 : #define BASE_REF_COUNTED_H_
7 :
8 : #include "base/atomic_ref_count.h"
9 : #include "base/thread_collision_warner.h"
10 :
11 : namespace base {
12 :
13 : namespace subtle {
14 :
15 : class RefCountedBase {
16 : protected:
17 : RefCountedBase();
18 : ~RefCountedBase();
19 :
20 : void AddRef();
21 :
22 : // Returns true if the object should self-delete.
23 : bool Release();
24 :
25 : private:
26 : int ref_count_;
27 : #ifndef NDEBUG
28 : bool in_dtor_;
29 : #endif
30 :
31 : DFAKE_MUTEX(add_release_);
32 :
33 : DISALLOW_COPY_AND_ASSIGN(RefCountedBase);
34 : };
35 :
36 : class RefCountedThreadSafeBase {
37 : protected:
38 : RefCountedThreadSafeBase();
39 : ~RefCountedThreadSafeBase();
40 :
41 : void AddRef();
42 :
43 : // Returns true if the object should self-delete.
44 : bool Release();
45 :
46 : private:
47 : AtomicRefCount ref_count_;
48 : #ifndef NDEBUG
49 : bool in_dtor_;
50 : #endif
51 :
52 : DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafeBase);
53 : };
54 :
55 :
56 :
57 : } // namespace subtle
58 :
59 : //
60 : // A base class for reference counted classes. Otherwise, known as a cheap
61 : // knock-off of WebKit's RefCounted<T> class. To use this guy just extend your
62 : // class from it like so:
63 : //
64 : // class MyFoo : public base::RefCounted<MyFoo> {
65 : // ...
66 : // };
67 : //
68 : template <class T>
69 : class RefCounted : public subtle::RefCountedBase {
70 : public:
71 1 : RefCounted() { }
72 0 : ~RefCounted() { }
73 :
74 1 : void AddRef() {
75 1 : subtle::RefCountedBase::AddRef();
76 1 : }
77 :
78 0 : void Release() {
79 0 : if (subtle::RefCountedBase::Release()) {
80 0 : delete static_cast<T*>(this);
81 : }
82 0 : }
83 :
84 : private:
85 : DISALLOW_COPY_AND_ASSIGN(RefCounted<T>);
86 : };
87 :
88 : //
89 : // A thread-safe variant of RefCounted<T>
90 : //
91 : // class MyFoo : public base::RefCountedThreadSafe<MyFoo> {
92 : // ...
93 : // };
94 : //
95 : template <class T>
96 : class RefCountedThreadSafe : public subtle::RefCountedThreadSafeBase {
97 : public:
98 7145 : RefCountedThreadSafe() { }
99 5677 : ~RefCountedThreadSafe() { }
100 :
101 8564 : void AddRef() {
102 8564 : subtle::RefCountedThreadSafeBase::AddRef();
103 8564 : }
104 :
105 7096 : void Release() {
106 7096 : if (subtle::RefCountedThreadSafeBase::Release()) {
107 5677 : delete static_cast<T*>(this);
108 : }
109 7096 : }
110 :
111 : private:
112 : DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafe<T>);
113 : };
114 :
115 : //
116 : // A wrapper for some piece of data so we can place other things in
117 : // scoped_refptrs<>.
118 : //
119 : template<typename T>
120 : class RefCountedData : public base::RefCounted< base::RefCountedData<T> > {
121 : public:
122 : RefCountedData() : data() {}
123 : RefCountedData(const T& in_value) : data(in_value) {}
124 :
125 : T data;
126 : };
127 :
128 : } // namespace base
129 :
130 : //
131 : // A smart pointer class for reference counted objects. Use this class instead
132 : // of calling AddRef and Release manually on a reference counted object to
133 : // avoid common memory leaks caused by forgetting to Release an object
134 : // reference. Sample usage:
135 : //
136 : // class MyFoo : public RefCounted<MyFoo> {
137 : // ...
138 : // };
139 : //
140 : // void some_function() {
141 : // scoped_refptr<MyFoo> foo = new MyFoo();
142 : // foo->Method(param);
143 : // // |foo| is released when this function returns
144 : // }
145 : //
146 : // void some_other_function() {
147 : // scoped_refptr<MyFoo> foo = new MyFoo();
148 : // ...
149 : // foo = NULL; // explicitly releases |foo|
150 : // ...
151 : // if (foo)
152 : // foo->Method(param);
153 : // }
154 : //
155 : // The above examples show how scoped_refptr<T> acts like a pointer to T.
156 : // Given two scoped_refptr<T> classes, it is also possible to exchange
157 : // references between the two objects, like so:
158 : //
159 : // {
160 : // scoped_refptr<MyFoo> a = new MyFoo();
161 : // scoped_refptr<MyFoo> b;
162 : //
163 : // b.swap(a);
164 : // // now, |b| references the MyFoo object, and |a| references NULL.
165 : // }
166 : //
167 : // To make both |a| and |b| in the above example reference the same MyFoo
168 : // object, simply use the assignment operator:
169 : //
170 : // {
171 : // scoped_refptr<MyFoo> a = new MyFoo();
172 : // scoped_refptr<MyFoo> b;
173 : //
174 : // b = a;
175 : // // now, |a| and |b| each own a reference to the same MyFoo object.
176 : // }
177 : //
178 : template <class T>
179 : class scoped_refptr {
180 : public:
181 4263 : scoped_refptr() : ptr_(NULL) {
182 4263 : }
183 :
184 4306 : scoped_refptr(T* p) : ptr_(p) {
185 4306 : if (ptr_)
186 4305 : ptr_->AddRef();
187 4306 : }
188 :
189 0 : scoped_refptr(const scoped_refptr<T>& r) : ptr_(r.ptr_) {
190 0 : if (ptr_)
191 0 : ptr_->AddRef();
192 0 : }
193 :
194 7096 : ~scoped_refptr() {
195 7096 : if (ptr_)
196 7096 : ptr_->Release();
197 7096 : }
198 :
199 0 : T* get() const { return ptr_; }
200 0 : operator T*() const { return ptr_; }
201 22712 : T* operator->() const { return ptr_; }
202 :
203 4260 : scoped_refptr<T>& operator=(T* p) {
204 : // AddRef first so that self assignment should work
205 4260 : if (p)
206 4260 : p->AddRef();
207 4260 : if (ptr_ )
208 0 : ptr_ ->Release();
209 4260 : ptr_ = p;
210 4260 : return *this;
211 : }
212 :
213 1419 : scoped_refptr<T>& operator=(const scoped_refptr<T>& r) {
214 1419 : return *this = r.ptr_;
215 : }
216 :
217 : void swap(T** pp) {
218 : T* p = ptr_;
219 : ptr_ = *pp;
220 : *pp = p;
221 : }
222 :
223 : void swap(scoped_refptr<T>& r) {
224 : swap(&r.ptr_);
225 : }
226 :
227 : protected:
228 : T* ptr_;
229 : };
230 :
231 : #endif // BASE_REF_COUNTED_H_
|