• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2014 Marshall A. Greenblatt. Portions copyright (c) 2012
2 // Google Inc. All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 //    * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 //    * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 //    * Neither the name of Google Inc. nor the name Chromium Embedded
15 // Framework nor the names of its contributors may be used to endorse
16 // or promote products derived from this software without specific prior
17 // written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 //
31 
32 #ifndef CEF_INCLUDE_BASE_CEF_REF_COUNTED_H_
33 #define CEF_INCLUDE_BASE_CEF_REF_COUNTED_H_
34 #pragma once
35 
36 #if defined(BASE_MEMORY_REF_COUNTED_H_)
37 // Do nothing if the Chromium header has already been included.
38 // This can happen in cases where Chromium code is used directly by the
39 // client application. When using Chromium code directly always include
40 // the Chromium header first to avoid type conflicts.
41 #elif defined(USING_CHROMIUM_INCLUDES)
42 // When building CEF include the Chromium header directly.
43 #include "base/memory/ref_counted.h"
44 #else  // !USING_CHROMIUM_INCLUDES
45 // The following is substantially similar to the Chromium implementation.
46 // If the Chromium implementation diverges the below implementation should be
47 // updated to match.
48 
49 #include <cassert>
50 
51 #include "include/base/cef_atomic_ref_count.h"
52 #include "include/base/cef_build.h"
53 #include "include/base/cef_logging.h"
54 #include "include/base/cef_macros.h"
55 
56 namespace base {
57 
58 namespace cef_subtle {
59 
60 class RefCountedBase {
61  public:
HasOneRef()62   bool HasOneRef() const { return ref_count_ == 1; }
HasAtLeastOneRef()63   bool HasAtLeastOneRef() const { return ref_count_ >= 1; }
64 
65  protected:
RefCountedBase()66   RefCountedBase()
67       : ref_count_(0)
68 #if DCHECK_IS_ON()
69         ,
70         in_dtor_(false)
71 #endif
72   {
73   }
74 
~RefCountedBase()75   ~RefCountedBase() {
76 #if DCHECK_IS_ON()
77     DCHECK(in_dtor_) << "RefCounted object deleted without calling Release()";
78 #endif
79   }
80 
AddRef()81   void AddRef() const {
82 #if DCHECK_IS_ON()
83     DCHECK(!in_dtor_);
84 #endif
85     ++ref_count_;
86   }
87 
88   // Returns true if the object should self-delete.
Release()89   bool Release() const {
90 #if DCHECK_IS_ON()
91     DCHECK(!in_dtor_);
92 #endif
93     if (--ref_count_ == 0) {
94 #if DCHECK_IS_ON()
95       in_dtor_ = true;
96 #endif
97       return true;
98     }
99     return false;
100   }
101 
102  private:
103   mutable int ref_count_;
104 #if DCHECK_IS_ON()
105   mutable bool in_dtor_;
106 #endif
107 
108   DISALLOW_COPY_AND_ASSIGN(RefCountedBase);
109 };
110 
111 class RefCountedThreadSafeBase {
112  public:
113   bool HasOneRef() const;
114   bool HasAtLeastOneRef() const;
115 
116  protected:
117   RefCountedThreadSafeBase();
118   ~RefCountedThreadSafeBase();
119 
120   void AddRef() const;
121 
122   // Returns true if the object should self-delete.
123   bool Release() const;
124 
125  private:
126   mutable AtomicRefCount ref_count_;
127 #if DCHECK_IS_ON()
128   mutable bool in_dtor_;
129 #endif
130 
131   DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafeBase);
132 };
133 
134 }  // namespace cef_subtle
135 
136 //
137 // A base class for reference counted classes.  Otherwise, known as a cheap
138 // knock-off of WebKit's RefCounted<T> class.  To use this guy just extend your
139 // class from it like so:
140 //
141 //   class MyFoo : public base::RefCounted<MyFoo> {
142 //    ...
143 //    private:
144 //     friend class base::RefCounted<MyFoo>;
145 //     ~MyFoo();
146 //   };
147 //
148 // You should always make your destructor private, to avoid any code deleting
149 // the object accidently while there are references to it.
150 template <class T>
151 class RefCounted : public cef_subtle::RefCountedBase {
152  public:
RefCounted()153   RefCounted() {}
154 
AddRef()155   void AddRef() const { cef_subtle::RefCountedBase::AddRef(); }
156 
Release()157   void Release() const {
158     if (cef_subtle::RefCountedBase::Release()) {
159       delete static_cast<const T*>(this);
160     }
161   }
162 
163  protected:
~RefCounted()164   ~RefCounted() {}
165 
166  private:
167   DISALLOW_COPY_AND_ASSIGN(RefCounted<T>);
168 };
169 
170 // Forward declaration.
171 template <class T, typename Traits>
172 class RefCountedThreadSafe;
173 
174 // Default traits for RefCountedThreadSafe<T>.  Deletes the object when its ref
175 // count reaches 0.  Overload to delete it on a different thread etc.
176 template <typename T>
177 struct DefaultRefCountedThreadSafeTraits {
DestructDefaultRefCountedThreadSafeTraits178   static void Destruct(const T* x) {
179     // Delete through RefCountedThreadSafe to make child classes only need to be
180     // friend with RefCountedThreadSafe instead of this struct, which is an
181     // implementation detail.
182     RefCountedThreadSafe<T, DefaultRefCountedThreadSafeTraits>::DeleteInternal(
183         x);
184   }
185 };
186 
187 //
188 // A thread-safe variant of RefCounted<T>
189 //
190 //   class MyFoo : public base::RefCountedThreadSafe<MyFoo> {
191 //    ...
192 //   };
193 //
194 // If you're using the default trait, then you should add compile time
195 // asserts that no one else is deleting your object.  i.e.
196 //    private:
197 //     friend class base::RefCountedThreadSafe<MyFoo>;
198 //     ~MyFoo();
199 template <class T, typename Traits = DefaultRefCountedThreadSafeTraits<T>>
200 class RefCountedThreadSafe : public cef_subtle::RefCountedThreadSafeBase {
201  public:
RefCountedThreadSafe()202   RefCountedThreadSafe() {}
203 
AddRef()204   void AddRef() const { cef_subtle::RefCountedThreadSafeBase::AddRef(); }
205 
Release()206   void Release() const {
207     if (cef_subtle::RefCountedThreadSafeBase::Release()) {
208       Traits::Destruct(static_cast<const T*>(this));
209     }
210   }
211 
212  protected:
~RefCountedThreadSafe()213   ~RefCountedThreadSafe() {}
214 
215  private:
216   friend struct DefaultRefCountedThreadSafeTraits<T>;
217   static void DeleteInternal(const T* x) { delete x; }
218 
219   DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafe);
220 };
221 
222 //
223 // A thread-safe wrapper for some piece of data so we can place other
224 // things in scoped_refptrs<>.
225 //
226 template <typename T>
227 class RefCountedData
228     : public base::RefCountedThreadSafe<base::RefCountedData<T>> {
229  public:
230   RefCountedData() : data() {}
231   RefCountedData(const T& in_value) : data(in_value) {}
232 
233   T data;
234 
235  private:
236   friend class base::RefCountedThreadSafe<base::RefCountedData<T>>;
237   ~RefCountedData() {}
238 };
239 
240 }  // namespace base
241 
242 //
243 // A smart pointer class for reference counted objects.  Use this class instead
244 // of calling AddRef and Release manually on a reference counted object to
245 // avoid common memory leaks caused by forgetting to Release an object
246 // reference.  Sample usage:
247 //
248 //   class MyFoo : public RefCounted<MyFoo> {
249 //    ...
250 //   };
251 //
252 //   void some_function() {
253 //     scoped_refptr<MyFoo> foo = new MyFoo();
254 //     foo->Method(param);
255 //     // |foo| is released when this function returns
256 //   }
257 //
258 //   void some_other_function() {
259 //     scoped_refptr<MyFoo> foo = new MyFoo();
260 //     ...
261 //     foo = NULL;  // explicitly releases |foo|
262 //     ...
263 //     if (foo)
264 //       foo->Method(param);
265 //   }
266 //
267 // The above examples show how scoped_refptr<T> acts like a pointer to T.
268 // Given two scoped_refptr<T> classes, it is also possible to exchange
269 // references between the two objects, like so:
270 //
271 //   {
272 //     scoped_refptr<MyFoo> a = new MyFoo();
273 //     scoped_refptr<MyFoo> b;
274 //
275 //     b.swap(a);
276 //     // now, |b| references the MyFoo object, and |a| references NULL.
277 //   }
278 //
279 // To make both |a| and |b| in the above example reference the same MyFoo
280 // object, simply use the assignment operator:
281 //
282 //   {
283 //     scoped_refptr<MyFoo> a = new MyFoo();
284 //     scoped_refptr<MyFoo> b;
285 //
286 //     b = a;
287 //     // now, |a| and |b| each own a reference to the same MyFoo object.
288 //   }
289 //
290 template <class T>
291 class scoped_refptr {
292  public:
293   typedef T element_type;
294 
295   scoped_refptr() : ptr_(NULL) {}
296 
297   scoped_refptr(T* p) : ptr_(p) {
298     if (ptr_)
299       ptr_->AddRef();
300   }
301 
302   scoped_refptr(const scoped_refptr<T>& r) : ptr_(r.ptr_) {
303     if (ptr_)
304       ptr_->AddRef();
305   }
306 
307   template <typename U>
308   scoped_refptr(const scoped_refptr<U>& r) : ptr_(r.get()) {
309     if (ptr_)
310       ptr_->AddRef();
311   }
312 
313   ~scoped_refptr() {
314     if (ptr_)
315       ptr_->Release();
316   }
317 
318   T* get() const { return ptr_; }
319 
320   // Allow scoped_refptr<C> to be used in boolean expression
321   // and comparison operations.
322   operator T*() const { return ptr_; }
323 
324   T* operator->() const {
325     assert(ptr_ != NULL);
326     return ptr_;
327   }
328 
329   scoped_refptr<T>& operator=(T* p) {
330     // AddRef first so that self assignment should work
331     if (p)
332       p->AddRef();
333     T* old_ptr = ptr_;
334     ptr_ = p;
335     if (old_ptr)
336       old_ptr->Release();
337     return *this;
338   }
339 
340   scoped_refptr<T>& operator=(const scoped_refptr<T>& r) {
341     return *this = r.ptr_;
342   }
343 
344   template <typename U>
345   scoped_refptr<T>& operator=(const scoped_refptr<U>& r) {
346     return *this = r.get();
347   }
348 
349   void swap(T** pp) {
350     T* p = ptr_;
351     ptr_ = *pp;
352     *pp = p;
353   }
354 
355   void swap(scoped_refptr<T>& r) { swap(&r.ptr_); }
356 
357  protected:
358   T* ptr_;
359 };
360 
361 // Handy utility for creating a scoped_refptr<T> out of a T* explicitly without
362 // having to retype all the template arguments
363 template <typename T>
364 scoped_refptr<T> make_scoped_refptr(T* t) {
365   return scoped_refptr<T>(t);
366 }
367 
368 #endif  // !USING_CHROMIUM_INCLUDES
369 
370 #endif  // CEF_INCLUDE_BASE_CEF_REF_COUNTED_H_
371