1 // Copyright (c) 2014 Marshall A. Greenblatt. Portions copyright (c) 2012
2 // Google Inc. All rights reserved.
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
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
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.
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.
32 #ifndef CEF_INCLUDE_BASE_CEF_REF_COUNTED_H_
33 #define CEF_INCLUDE_BASE_CEF_REF_COUNTED_H_
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(BUILDING_CEF_SHARED)
42 // When building CEF include the Chromium header directly.
43 #include "base/memory/ref_counted.h"
44 #else // !BUILDING_CEF_SHARED
45 // The following is substantially similar to the Chromium implementation.
46 // If the Chromium implementation diverges the below implementation should be
51 #include "include/base/cef_atomic_ref_count.h"
52 #include "include/base/cef_build.h"
54 #include "include/base/cef_logging.h"
56 #include "include/base/cef_thread_collision_warner.h"
62 class RefCountedBase {
64 bool HasOneRef() const { return ref_count_ == 1; }
77 DCHECK(in_dtor_) << "RefCounted object deleted without calling Release()";
83 // TODO(maruel): Add back once it doesn't assert 500 times/sec.
84 // Current thread books the critical section "AddRelease"
85 // without release it.
86 // DFAKE_SCOPED_LOCK_THREAD_LOCKED(add_release_);
93 // Returns true if the object should self-delete.
94 bool Release() const {
95 // TODO(maruel): Add back once it doesn't assert 500 times/sec.
96 // Current thread books the critical section "AddRelease"
97 // without release it.
98 // DFAKE_SCOPED_LOCK_THREAD_LOCKED(add_release_);
102 if (--ref_count_ == 0) {
112 mutable int ref_count_;
114 mutable bool in_dtor_;
117 DFAKE_MUTEX(add_release_);
119 DISALLOW_COPY_AND_ASSIGN(RefCountedBase);
122 class RefCountedThreadSafeBase {
124 bool HasOneRef() const;
127 RefCountedThreadSafeBase();
128 ~RefCountedThreadSafeBase();
132 // Returns true if the object should self-delete.
133 bool Release() const;
136 mutable AtomicRefCount ref_count_;
138 mutable bool in_dtor_;
141 DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafeBase);
144 } // namespace subtle
147 // A base class for reference counted classes. Otherwise, known as a cheap
148 // knock-off of WebKit's RefCounted<T> class. To use this guy just extend your
149 // class from it like so:
151 // class MyFoo : public base::RefCounted<MyFoo> {
154 // friend class base::RefCounted<MyFoo>;
158 // You should always make your destructor private, to avoid any code deleting
159 // the object accidently while there are references to it.
161 class RefCounted : public subtle::RefCountedBase {
165 void AddRef() const {
166 subtle::RefCountedBase::AddRef();
169 void Release() const {
170 if (subtle::RefCountedBase::Release()) {
171 delete static_cast<const T*>(this);
179 DISALLOW_COPY_AND_ASSIGN(RefCounted<T>);
182 // Forward declaration.
183 template <class T, typename Traits> class RefCountedThreadSafe;
185 // Default traits for RefCountedThreadSafe<T>. Deletes the object when its ref
186 // count reaches 0. Overload to delete it on a different thread etc.
188 struct DefaultRefCountedThreadSafeTraits {
189 static void Destruct(const T* x) {
190 // Delete through RefCountedThreadSafe to make child classes only need to be
191 // friend with RefCountedThreadSafe instead of this struct, which is an
192 // implementation detail.
193 RefCountedThreadSafe<T,
194 DefaultRefCountedThreadSafeTraits>::DeleteInternal(x);
199 // A thread-safe variant of RefCounted<T>
201 // class MyFoo : public base::RefCountedThreadSafe<MyFoo> {
205 // If you're using the default trait, then you should add compile time
206 // asserts that no one else is deleting your object. i.e.
208 // friend class base::RefCountedThreadSafe<MyFoo>;
210 template <class T, typename Traits = DefaultRefCountedThreadSafeTraits<T> >
211 class RefCountedThreadSafe : public subtle::RefCountedThreadSafeBase {
213 RefCountedThreadSafe() {}
215 void AddRef() const {
216 subtle::RefCountedThreadSafeBase::AddRef();
219 void Release() const {
220 if (subtle::RefCountedThreadSafeBase::Release()) {
221 Traits::Destruct(static_cast<const T*>(this));
226 ~RefCountedThreadSafe() {}
229 friend struct DefaultRefCountedThreadSafeTraits<T>;
230 static void DeleteInternal(const T* x) { delete x; }
232 DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafe);
236 // A thread-safe wrapper for some piece of data so we can place other
237 // things in scoped_refptrs<>.
241 : public base::RefCountedThreadSafe< base::RefCountedData<T> > {
243 RefCountedData() : data() {}
244 RefCountedData(const T& in_value) : data(in_value) {}
249 friend class base::RefCountedThreadSafe<base::RefCountedData<T> >;
256 // A smart pointer class for reference counted objects. Use this class instead
257 // of calling AddRef and Release manually on a reference counted object to
258 // avoid common memory leaks caused by forgetting to Release an object
259 // reference. Sample usage:
261 // class MyFoo : public RefCounted<MyFoo> {
265 // void some_function() {
266 // scoped_refptr<MyFoo> foo = new MyFoo();
267 // foo->Method(param);
268 // // |foo| is released when this function returns
271 // void some_other_function() {
272 // scoped_refptr<MyFoo> foo = new MyFoo();
274 // foo = NULL; // explicitly releases |foo|
277 // foo->Method(param);
280 // The above examples show how scoped_refptr<T> acts like a pointer to T.
281 // Given two scoped_refptr<T> classes, it is also possible to exchange
282 // references between the two objects, like so:
285 // scoped_refptr<MyFoo> a = new MyFoo();
286 // scoped_refptr<MyFoo> b;
289 // // now, |b| references the MyFoo object, and |a| references NULL.
292 // To make both |a| and |b| in the above example reference the same MyFoo
293 // object, simply use the assignment operator:
296 // scoped_refptr<MyFoo> a = new MyFoo();
297 // scoped_refptr<MyFoo> b;
300 // // now, |a| and |b| each own a reference to the same MyFoo object.
304 class scoped_refptr {
306 typedef T element_type;
308 scoped_refptr() : ptr_(NULL) {
311 scoped_refptr(T* p) : ptr_(p) {
316 scoped_refptr(const scoped_refptr<T>& r) : ptr_(r.ptr_) {
321 template <typename U>
322 scoped_refptr(const scoped_refptr<U>& r) : ptr_(r.get()) {
332 T* get() const { return ptr_; }
334 // Allow scoped_refptr<C> to be used in boolean expression
335 // and comparison operations.
336 operator T*() const { return ptr_; }
338 T* operator->() const {
339 assert(ptr_ != NULL);
343 scoped_refptr<T>& operator=(T* p) {
344 // AddRef first so that self assignment should work
354 scoped_refptr<T>& operator=(const scoped_refptr<T>& r) {
355 return *this = r.ptr_;
358 template <typename U>
359 scoped_refptr<T>& operator=(const scoped_refptr<U>& r) {
360 return *this = r.get();
369 void swap(scoped_refptr<T>& r) {
377 // Handy utility for creating a scoped_refptr<T> out of a T* explicitly without
378 // having to retype all the template arguments
379 template <typename T>
380 scoped_refptr<T> make_scoped_refptr(T* t) {
381 return scoped_refptr<T>(t);
384 #endif // !BUILDING_CEF_SHARED
386 #endif // CEF_INCLUDE_BASE_CEF_REF_COUNTED_H_