Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
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.
5 #ifndef BASE_REF_COUNTED_H_
6 #define BASE_REF_COUNTED_H_
8 #include "base/atomic_ref_count.h"
9 #include "base/thread_collision_warner.h"
11 namespace base {
13 namespace subtle {
15 class RefCountedBase {
16 protected:
17 RefCountedBase();
18 ~RefCountedBase();
20 void AddRef();
22 // Returns true if the object should self-delete.
23 bool Release();
25 private:
26 int ref_count_;
27 #ifndef NDEBUG
28 bool in_dtor_;
29 #endif
31 DFAKE_MUTEX(add_release_)
33 DISALLOW_COPY_AND_ASSIGN(RefCountedBase);
34 };
36 class RefCountedThreadSafeBase {
37 protected:
38 RefCountedThreadSafeBase();
39 ~RefCountedThreadSafeBase();
41 void AddRef();
43 // Returns true if the object should self-delete.
44 bool Release();
46 private:
47 AtomicRefCount ref_count_;
48 #ifndef NDEBUG
49 bool in_dtor_;
50 #endif
52 DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafeBase);
53 };
57 } // namespace subtle
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 RefCounted() { }
72 ~RefCounted() { }
74 void AddRef() {
75 subtle::RefCountedBase::AddRef();
76 }
78 void Release() {
79 if (subtle::RefCountedBase::Release()) {
80 delete static_cast<T*>(this);
81 }
82 }
84 private:
85 DISALLOW_COPY_AND_ASSIGN(RefCounted<T>);
86 };
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 RefCountedThreadSafe() { }
99 ~RefCountedThreadSafe() { }
101 void AddRef() {
102 subtle::RefCountedThreadSafeBase::AddRef();
103 }
105 void Release() {
106 if (subtle::RefCountedThreadSafeBase::Release()) {
107 delete static_cast<T*>(this);
108 }
109 }
111 private:
112 DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafe<T>);
113 };
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) {}
125 T data;
126 };
128 } // namespace base
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 scoped_refptr() : ptr_(NULL) {
182 }
184 scoped_refptr(T* p) : ptr_(p) {
185 if (ptr_)
186 ptr_->AddRef();
187 }
189 scoped_refptr(const scoped_refptr<T>& r) : ptr_(r.ptr_) {
190 if (ptr_)
191 ptr_->AddRef();
192 }
194 ~scoped_refptr() {
195 if (ptr_)
196 ptr_->Release();
197 }
199 T* get() const { return ptr_; }
200 operator T*() const { return ptr_; }
201 T* operator->() const { return ptr_; }
203 scoped_refptr<T>& operator=(T* p) {
204 // AddRef first so that self assignment should work
205 if (p)
206 p->AddRef();
207 if (ptr_ )
208 ptr_ ->Release();
209 ptr_ = p;
210 return *this;
211 }
213 scoped_refptr<T>& operator=(const scoped_refptr<T>& r) {
214 return *this = r.ptr_;
215 }
217 void swap(T** pp) {
218 T* p = ptr_;
219 ptr_ = *pp;
220 *pp = p;
221 }
223 void swap(scoped_refptr<T>& r) {
224 swap(&r.ptr_);
225 }
227 protected:
228 T* ptr_;
229 };
231 #endif // BASE_REF_COUNTED_H_