Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/include/ref_counted.h

Issue 4210003: Started on Resource class. (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client
Patch Set: Resource->PluginResource Created 10 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | src/shared/ppapi_proxy/build.scons » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2010 The Native Client 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 NATIVE_CLIENT_SRC_INCLUDE_REF_COUNTED_H_
6 #define NATIVE_CLIENT_SRC_INCLUDE_REF_COUNTED_H_
7
8 namespace nacl {
9
10 namespace subtle {
11
12 class RefCountedBase {
13 public:
14 static bool ImplementsThreadSafeReferenceCounting() { return false; }
15
16 bool HasOneRef() const { return ref_count_ == 1; }
17
18 protected:
19 RefCountedBase() : ref_count_(0) { }
20 ~RefCountedBase() { }
21
22 void AddRef() const { ++ref_count_; }
23
24 // Returns true if the object should self-delete.
25 bool Release() const { return --ref_count_ == 0; }
26
27 private:
28 mutable int ref_count_;
29
30 RefCountedBase(const RefCountedBase&);
31 void operator=(const RefCountedBase&);
32 };
33
34 } // namespace subtle
35
36 //
37 // A base class for reference counted classes. Otherwise, known as a cheap
38 // knock-off of WebKit's RefCounted<T> class. To use this guy just extend your
39 // class from it like so:
40 //
41 // class MyFoo : public nacl::RefCounted<MyFoo> {
42 // ...
43 // private:
44 // friend class nacl::RefCounted<MyFoo>;
45 // ~MyFoo();
46 // };
47 //
48 // You should always make your destructor private, to avoid any code deleting
49 // the object accidently while there are references to it.
50 template <class T>
51 class RefCounted : public subtle::RefCountedBase {
52 public:
53 RefCounted() { }
54 ~RefCounted() { }
55
56 void AddRef() const {
57 subtle::RefCountedBase::AddRef();
58 }
59
60 void Release() const {
61 if (subtle::RefCountedBase::Release()) {
62 delete static_cast<const T*>(this);
63 }
64 }
65
66 private:
67 RefCounted(const RefCounted<T>&);
68 void operator=(const RefCounted<T>&);
69 };
70
71 //
72 // A wrapper for some piece of data so we can place other things in
73 // scoped_refptrs<>.
74 //
75 template<typename T>
76 class RefCountedData : public nacl::RefCounted< nacl::RefCountedData<T> > {
77 public:
78 RefCountedData() : data() {}
79 RefCountedData(const T& in_value) : data(in_value) {}
80
81 T data;
82 };
83
84 } // namespace nacl
85
86 //
87 // A smart pointer class for reference counted objects. Use this class instead
88 // of calling AddRef and Release manually on a reference counted object to
89 // avoid common memory leaks caused by forgetting to Release an object
90 // reference. Sample usage:
91 //
92 // class MyFoo : public RefCounted<MyFoo> {
93 // ...
94 // };
95 //
96 // void some_function() {
97 // scoped_refptr<MyFoo> foo = new MyFoo();
98 // foo->Method(param);
99 // // |foo| is released when this function returns
100 // }
101 //
102 // void some_other_function() {
103 // scoped_refptr<MyFoo> foo = new MyFoo();
104 // ...
105 // foo = NULL; // explicitly releases |foo|
106 // ...
107 // if (foo)
108 // foo->Method(param);
109 // }
110 //
111 // The above examples show how scoped_refptr<T> acts like a pointer to T.
112 // Given two scoped_refptr<T> classes, it is also possible to exchange
113 // references between the two objects, like so:
114 //
115 // {
116 // scoped_refptr<MyFoo> a = new MyFoo();
117 // scoped_refptr<MyFoo> b;
118 //
119 // b.swap(a);
120 // // now, |b| references the MyFoo object, and |a| references NULL.
121 // }
122 //
123 // To make both |a| and |b| in the above example reference the same MyFoo
124 // object, simply use the assignment operator:
125 //
126 // {
127 // scoped_refptr<MyFoo> a = new MyFoo();
128 // scoped_refptr<MyFoo> b;
129 //
130 // b = a;
131 // // now, |a| and |b| each own a reference to the same MyFoo object.
132 // }
133 //
134 template <class T>
135 class scoped_refptr {
136 public:
137 scoped_refptr() : ptr_((T*)0) {
138 }
139
140 scoped_refptr(T* p) : ptr_(p) {
141 if (ptr_)
142 ptr_->AddRef();
143 }
144
145 scoped_refptr(const scoped_refptr<T>& r) : ptr_(r.ptr_) {
146 if (ptr_)
147 ptr_->AddRef();
148 }
149
150 template <typename U>
151 scoped_refptr(const scoped_refptr<U>& r) : ptr_(r.get()) {
152 if (ptr_)
153 ptr_->AddRef();
154 }
155
156 ~scoped_refptr() {
157 if (ptr_)
158 ptr_->Release();
159 }
160
161 T* get() const { return ptr_; }
162 operator T*() const { return ptr_; }
163 T* operator->() const { return ptr_; }
164
165 // Release a pointer.
166 // The return value is the current pointer held by this object.
167 // If this object holds a NULL pointer, the return value is NULL.
168 // After this operation, this object will hold a NULL pointer,
169 // and will not own the object any more.
170 T* release() {
171 T* retVal = ptr_;
172 ptr_ = (void*)0;
173 return retVal;
174 }
175
176 scoped_refptr<T>& operator=(T* p) {
177 // AddRef first so that self assignment should work
178 if (p)
179 p->AddRef();
180 if (ptr_ )
181 ptr_ ->Release();
182 ptr_ = p;
183 return *this;
184 }
185
186 scoped_refptr<T>& operator=(const scoped_refptr<T>& r) {
187 return *this = r.ptr_;
188 }
189
190 template <typename U>
191 scoped_refptr<T>& operator=(const scoped_refptr<U>& r) {
192 return *this = r.get();
193 }
194
195 void swap(T** pp) {
196 T* p = ptr_;
197 ptr_ = *pp;
198 *pp = p;
199 }
200
201 void swap(scoped_refptr<T>& r) {
202 swap(&r.ptr_);
203 }
204
205 protected:
206 T* ptr_;
207 };
208
209 // Handy utility for creating a scoped_refptr<T> out of a T* explicitly without
210 // having to retype all the template arguments
211 template <typename T>
212 scoped_refptr<T> make_scoped_refptr(T* t) {
213 return scoped_refptr<T>(t);
214 }
215
216 #endif // NATIVE_CLIENT_SRC_INCLUDE_REF_COUNTED_H_
217
OLDNEW
« no previous file with comments | « no previous file | src/shared/ppapi_proxy/build.scons » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698