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

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

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

Powered by Google App Engine
This is Rietveld 408576698