]> git.sesse.net Git - casparcg/blob - dependencies64/cef/include/base/cef_ref_counted.h
* Merged html producer and updated to latest CEF version (does not have satisfactory...
[casparcg] / dependencies64 / cef / include / base / cef_ref_counted.h
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(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
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 #ifndef NDEBUG
54 #include "include/base/cef_logging.h"
55 #endif
56 #include "include/base/cef_thread_collision_warner.h"
57
58 namespace base {
59
60 namespace subtle {
61
62 class RefCountedBase {
63  public:
64   bool HasOneRef() const { return ref_count_ == 1; }
65
66  protected:
67   RefCountedBase()
68       : ref_count_(0)
69   #ifndef NDEBUG
70       , in_dtor_(false)
71   #endif
72       {
73   }
74
75   ~RefCountedBase() {
76   #ifndef NDEBUG
77     DCHECK(in_dtor_) << "RefCounted object deleted without calling Release()";
78   #endif
79   }
80
81
82   void AddRef() const {
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_);
87   #ifndef NDEBUG
88     DCHECK(!in_dtor_);
89   #endif
90     ++ref_count_;
91   }
92
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_);
99   #ifndef NDEBUG
100     DCHECK(!in_dtor_);
101   #endif
102     if (--ref_count_ == 0) {
103   #ifndef NDEBUG
104       in_dtor_ = true;
105   #endif
106       return true;
107     }
108     return false;
109   }
110
111  private:
112   mutable int ref_count_;
113 #ifndef NDEBUG
114   mutable bool in_dtor_;
115 #endif
116
117   DFAKE_MUTEX(add_release_);
118
119   DISALLOW_COPY_AND_ASSIGN(RefCountedBase);
120 };
121
122 class RefCountedThreadSafeBase {
123  public:
124   bool HasOneRef() const;
125
126  protected:
127   RefCountedThreadSafeBase();
128   ~RefCountedThreadSafeBase();
129
130   void AddRef() const;
131
132   // Returns true if the object should self-delete.
133   bool Release() const;
134
135  private:
136   mutable AtomicRefCount ref_count_;
137 #ifndef NDEBUG
138   mutable bool in_dtor_;
139 #endif
140
141   DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafeBase);
142 };
143
144 }  // namespace subtle
145
146 //
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:
150 //
151 //   class MyFoo : public base::RefCounted<MyFoo> {
152 //    ...
153 //    private:
154 //     friend class base::RefCounted<MyFoo>;
155 //     ~MyFoo();
156 //   };
157 //
158 // You should always make your destructor private, to avoid any code deleting
159 // the object accidently while there are references to it.
160 template <class T>
161 class RefCounted : public subtle::RefCountedBase {
162  public:
163   RefCounted() {}
164
165   void AddRef() const {
166     subtle::RefCountedBase::AddRef();
167   }
168
169   void Release() const {
170     if (subtle::RefCountedBase::Release()) {
171       delete static_cast<const T*>(this);
172     }
173   }
174
175  protected:
176   ~RefCounted() {}
177
178  private:
179   DISALLOW_COPY_AND_ASSIGN(RefCounted<T>);
180 };
181
182 // Forward declaration.
183 template <class T, typename Traits> class RefCountedThreadSafe;
184
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.
187 template<typename T>
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);
195   }
196 };
197
198 //
199 // A thread-safe variant of RefCounted<T>
200 //
201 //   class MyFoo : public base::RefCountedThreadSafe<MyFoo> {
202 //    ...
203 //   };
204 //
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.
207 //    private:
208 //     friend class base::RefCountedThreadSafe<MyFoo>;
209 //     ~MyFoo();
210 template <class T, typename Traits = DefaultRefCountedThreadSafeTraits<T> >
211 class RefCountedThreadSafe : public subtle::RefCountedThreadSafeBase {
212  public:
213   RefCountedThreadSafe() {}
214
215   void AddRef() const {
216     subtle::RefCountedThreadSafeBase::AddRef();
217   }
218
219   void Release() const {
220     if (subtle::RefCountedThreadSafeBase::Release()) {
221       Traits::Destruct(static_cast<const T*>(this));
222     }
223   }
224
225  protected:
226   ~RefCountedThreadSafe() {}
227
228  private:
229   friend struct DefaultRefCountedThreadSafeTraits<T>;
230   static void DeleteInternal(const T* x) { delete x; }
231
232   DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafe);
233 };
234
235 //
236 // A thread-safe wrapper for some piece of data so we can place other
237 // things in scoped_refptrs<>.
238 //
239 template<typename T>
240 class RefCountedData
241     : public base::RefCountedThreadSafe< base::RefCountedData<T> > {
242  public:
243   RefCountedData() : data() {}
244   RefCountedData(const T& in_value) : data(in_value) {}
245
246   T data;
247
248  private:
249   friend class base::RefCountedThreadSafe<base::RefCountedData<T> >;
250   ~RefCountedData() {}
251 };
252
253 }  // namespace base
254
255 //
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:
260 //
261 //   class MyFoo : public RefCounted<MyFoo> {
262 //    ...
263 //   };
264 //
265 //   void some_function() {
266 //     scoped_refptr<MyFoo> foo = new MyFoo();
267 //     foo->Method(param);
268 //     // |foo| is released when this function returns
269 //   }
270 //
271 //   void some_other_function() {
272 //     scoped_refptr<MyFoo> foo = new MyFoo();
273 //     ...
274 //     foo = NULL;  // explicitly releases |foo|
275 //     ...
276 //     if (foo)
277 //       foo->Method(param);
278 //   }
279 //
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:
283 //
284 //   {
285 //     scoped_refptr<MyFoo> a = new MyFoo();
286 //     scoped_refptr<MyFoo> b;
287 //
288 //     b.swap(a);
289 //     // now, |b| references the MyFoo object, and |a| references NULL.
290 //   }
291 //
292 // To make both |a| and |b| in the above example reference the same MyFoo
293 // object, simply use the assignment operator:
294 //
295 //   {
296 //     scoped_refptr<MyFoo> a = new MyFoo();
297 //     scoped_refptr<MyFoo> b;
298 //
299 //     b = a;
300 //     // now, |a| and |b| each own a reference to the same MyFoo object.
301 //   }
302 //
303 template <class T>
304 class scoped_refptr {
305  public:
306   typedef T element_type;
307
308   scoped_refptr() : ptr_(NULL) {
309   }
310
311   scoped_refptr(T* p) : ptr_(p) {
312     if (ptr_)
313       ptr_->AddRef();
314   }
315
316   scoped_refptr(const scoped_refptr<T>& r) : ptr_(r.ptr_) {
317     if (ptr_)
318       ptr_->AddRef();
319   }
320
321   template <typename U>
322   scoped_refptr(const scoped_refptr<U>& r) : ptr_(r.get()) {
323     if (ptr_)
324       ptr_->AddRef();
325   }
326
327   ~scoped_refptr() {
328     if (ptr_)
329       ptr_->Release();
330   }
331
332   T* get() const { return ptr_; }
333
334   // Allow scoped_refptr<C> to be used in boolean expression
335   // and comparison operations.
336   operator T*() const { return ptr_; }
337
338   T* operator->() const {
339     assert(ptr_ != NULL);
340     return ptr_;
341   }
342
343   scoped_refptr<T>& operator=(T* p) {
344     // AddRef first so that self assignment should work
345     if (p)
346       p->AddRef();
347     T* old_ptr = ptr_;
348     ptr_ = p;
349     if (old_ptr)
350       old_ptr->Release();
351     return *this;
352   }
353
354   scoped_refptr<T>& operator=(const scoped_refptr<T>& r) {
355     return *this = r.ptr_;
356   }
357
358   template <typename U>
359   scoped_refptr<T>& operator=(const scoped_refptr<U>& r) {
360     return *this = r.get();
361   }
362
363   void swap(T** pp) {
364     T* p = ptr_;
365     ptr_ = *pp;
366     *pp = p;
367   }
368
369   void swap(scoped_refptr<T>& r) {
370     swap(&r.ptr_);
371   }
372
373  protected:
374   T* ptr_;
375 };
376
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);
382 }
383
384 #endif  // !BUILDING_CEF_SHARED
385
386 #endif  // CEF_INCLUDE_BASE_CEF_REF_COUNTED_H_