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