| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 The Chromium 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. | |
| 4 | |
| 5 #ifndef BASE_MEMORY_REF_COUNTED_H_ | |
| 6 #define BASE_MEMORY_REF_COUNTED_H_ | |
| 7 | |
| 8 #include <cassert> | |
| 9 #include <iosfwd> | |
| 10 | |
| 11 #include "base/atomic_ref_count.h" | |
| 12 #include "base/base_export.h" | |
| 13 #include "base/compiler_specific.h" | |
| 14 #ifndef NDEBUG | |
| 15 #include "base/logging.h" | |
| 16 #endif | |
| 17 #include "base/move.h" | |
| 18 #include "base/threading/thread_collision_warner.h" | |
| 19 #include "build/build_config.h" | |
| 20 | |
| 21 namespace base { | |
| 22 | |
| 23 namespace subtle { | |
| 24 | |
| 25 class BASE_EXPORT RefCountedBase { | |
| 26 public: | |
| 27 bool HasOneRef() const { return ref_count_ == 1; } | |
| 28 | |
| 29 protected: | |
| 30 RefCountedBase() | |
| 31 : ref_count_(0) | |
| 32 #ifndef NDEBUG | |
| 33 , in_dtor_(false) | |
| 34 #endif | |
| 35 { | |
| 36 } | |
| 37 | |
| 38 ~RefCountedBase() { | |
| 39 #ifndef NDEBUG | |
| 40 DCHECK(in_dtor_) << "RefCounted object deleted without calling Release()"; | |
| 41 #endif | |
| 42 } | |
| 43 | |
| 44 | |
| 45 void AddRef() const { | |
| 46 // TODO(maruel): Add back once it doesn't assert 500 times/sec. | |
| 47 // Current thread books the critical section "AddRelease" | |
| 48 // without release it. | |
| 49 // DFAKE_SCOPED_LOCK_THREAD_LOCKED(add_release_); | |
| 50 #ifndef NDEBUG | |
| 51 DCHECK(!in_dtor_); | |
| 52 #endif | |
| 53 ++ref_count_; | |
| 54 } | |
| 55 | |
| 56 // Returns true if the object should self-delete. | |
| 57 bool Release() const { | |
| 58 // TODO(maruel): Add back once it doesn't assert 500 times/sec. | |
| 59 // Current thread books the critical section "AddRelease" | |
| 60 // without release it. | |
| 61 // DFAKE_SCOPED_LOCK_THREAD_LOCKED(add_release_); | |
| 62 #ifndef NDEBUG | |
| 63 DCHECK(!in_dtor_); | |
| 64 #endif | |
| 65 if (--ref_count_ == 0) { | |
| 66 #ifndef NDEBUG | |
| 67 in_dtor_ = true; | |
| 68 #endif | |
| 69 return true; | |
| 70 } | |
| 71 return false; | |
| 72 } | |
| 73 | |
| 74 private: | |
| 75 mutable int ref_count_; | |
| 76 #ifndef NDEBUG | |
| 77 mutable bool in_dtor_; | |
| 78 #endif | |
| 79 | |
| 80 DFAKE_MUTEX(add_release_); | |
| 81 | |
| 82 DISALLOW_COPY_AND_ASSIGN(RefCountedBase); | |
| 83 }; | |
| 84 | |
| 85 class BASE_EXPORT RefCountedThreadSafeBase { | |
| 86 public: | |
| 87 bool HasOneRef() const; | |
| 88 | |
| 89 protected: | |
| 90 RefCountedThreadSafeBase(); | |
| 91 ~RefCountedThreadSafeBase(); | |
| 92 | |
| 93 void AddRef() const; | |
| 94 | |
| 95 // Returns true if the object should self-delete. | |
| 96 bool Release() const; | |
| 97 | |
| 98 private: | |
| 99 mutable AtomicRefCount ref_count_; | |
| 100 #ifndef NDEBUG | |
| 101 mutable bool in_dtor_; | |
| 102 #endif | |
| 103 | |
| 104 DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafeBase); | |
| 105 }; | |
| 106 | |
| 107 } // namespace subtle | |
| 108 | |
| 109 // | |
| 110 // A base class for reference counted classes. Otherwise, known as a cheap | |
| 111 // knock-off of WebKit's RefCounted<T> class. To use this guy just extend your | |
| 112 // class from it like so: | |
| 113 // | |
| 114 // class MyFoo : public base::RefCounted<MyFoo> { | |
| 115 // ... | |
| 116 // private: | |
| 117 // friend class base::RefCounted<MyFoo>; | |
| 118 // ~MyFoo(); | |
| 119 // }; | |
| 120 // | |
| 121 // You should always make your destructor private, to avoid any code deleting | |
| 122 // the object accidently while there are references to it. | |
| 123 template <class T> | |
| 124 class RefCounted : public subtle::RefCountedBase { | |
| 125 public: | |
| 126 RefCounted() {} | |
| 127 | |
| 128 void AddRef() const { | |
| 129 subtle::RefCountedBase::AddRef(); | |
| 130 } | |
| 131 | |
| 132 void Release() const { | |
| 133 if (subtle::RefCountedBase::Release()) { | |
| 134 delete static_cast<const T*>(this); | |
| 135 } | |
| 136 } | |
| 137 | |
| 138 protected: | |
| 139 ~RefCounted() {} | |
| 140 | |
| 141 private: | |
| 142 DISALLOW_COPY_AND_ASSIGN(RefCounted<T>); | |
| 143 }; | |
| 144 | |
| 145 // Forward declaration. | |
| 146 template <class T, typename Traits> class RefCountedThreadSafe; | |
| 147 | |
| 148 // Default traits for RefCountedThreadSafe<T>. Deletes the object when its ref | |
| 149 // count reaches 0. Overload to delete it on a different thread etc. | |
| 150 template<typename T> | |
| 151 struct DefaultRefCountedThreadSafeTraits { | |
| 152 static void Destruct(const T* x) { | |
| 153 // Delete through RefCountedThreadSafe to make child classes only need to be | |
| 154 // friend with RefCountedThreadSafe instead of this struct, which is an | |
| 155 // implementation detail. | |
| 156 RefCountedThreadSafe<T, | |
| 157 DefaultRefCountedThreadSafeTraits>::DeleteInternal(x); | |
| 158 } | |
| 159 }; | |
| 160 | |
| 161 // | |
| 162 // A thread-safe variant of RefCounted<T> | |
| 163 // | |
| 164 // class MyFoo : public base::RefCountedThreadSafe<MyFoo> { | |
| 165 // ... | |
| 166 // }; | |
| 167 // | |
| 168 // If you're using the default trait, then you should add compile time | |
| 169 // asserts that no one else is deleting your object. i.e. | |
| 170 // private: | |
| 171 // friend class base::RefCountedThreadSafe<MyFoo>; | |
| 172 // ~MyFoo(); | |
| 173 template <class T, typename Traits = DefaultRefCountedThreadSafeTraits<T> > | |
| 174 class RefCountedThreadSafe : public subtle::RefCountedThreadSafeBase { | |
| 175 public: | |
| 176 RefCountedThreadSafe() {} | |
| 177 | |
| 178 void AddRef() const { | |
| 179 subtle::RefCountedThreadSafeBase::AddRef(); | |
| 180 } | |
| 181 | |
| 182 void Release() const { | |
| 183 if (subtle::RefCountedThreadSafeBase::Release()) { | |
| 184 Traits::Destruct(static_cast<const T*>(this)); | |
| 185 } | |
| 186 } | |
| 187 | |
| 188 protected: | |
| 189 ~RefCountedThreadSafe() {} | |
| 190 | |
| 191 private: | |
| 192 friend struct DefaultRefCountedThreadSafeTraits<T>; | |
| 193 static void DeleteInternal(const T* x) { delete x; } | |
| 194 | |
| 195 DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafe); | |
| 196 }; | |
| 197 | |
| 198 // | |
| 199 // A thread-safe wrapper for some piece of data so we can place other | |
| 200 // things in scoped_refptrs<>. | |
| 201 // | |
| 202 template<typename T> | |
| 203 class RefCountedData | |
| 204 : public base::RefCountedThreadSafe< base::RefCountedData<T> > { | |
| 205 public: | |
| 206 RefCountedData() : data() {} | |
| 207 RefCountedData(const T& in_value) : data(in_value) {} | |
| 208 | |
| 209 T data; | |
| 210 | |
| 211 private: | |
| 212 friend class base::RefCountedThreadSafe<base::RefCountedData<T> >; | |
| 213 ~RefCountedData() {} | |
| 214 }; | |
| 215 | |
| 216 } // namespace base | |
| 217 | |
| 218 // | |
| 219 // A smart pointer class for reference counted objects. Use this class instead | |
| 220 // of calling AddRef and Release manually on a reference counted object to | |
| 221 // avoid common memory leaks caused by forgetting to Release an object | |
| 222 // reference. Sample usage: | |
| 223 // | |
| 224 // class MyFoo : public RefCounted<MyFoo> { | |
| 225 // ... | |
| 226 // }; | |
| 227 // | |
| 228 // void some_function() { | |
| 229 // scoped_refptr<MyFoo> foo = new MyFoo(); | |
| 230 // foo->Method(param); | |
| 231 // // |foo| is released when this function returns | |
| 232 // } | |
| 233 // | |
| 234 // void some_other_function() { | |
| 235 // scoped_refptr<MyFoo> foo = new MyFoo(); | |
| 236 // ... | |
| 237 // foo = NULL; // explicitly releases |foo| | |
| 238 // ... | |
| 239 // if (foo) | |
| 240 // foo->Method(param); | |
| 241 // } | |
| 242 // | |
| 243 // The above examples show how scoped_refptr<T> acts like a pointer to T. | |
| 244 // Given two scoped_refptr<T> classes, it is also possible to exchange | |
| 245 // references between the two objects, like so: | |
| 246 // | |
| 247 // { | |
| 248 // scoped_refptr<MyFoo> a = new MyFoo(); | |
| 249 // scoped_refptr<MyFoo> b; | |
| 250 // | |
| 251 // b.swap(a); | |
| 252 // // now, |b| references the MyFoo object, and |a| references NULL. | |
| 253 // } | |
| 254 // | |
| 255 // To make both |a| and |b| in the above example reference the same MyFoo | |
| 256 // object, simply use the assignment operator: | |
| 257 // | |
| 258 // { | |
| 259 // scoped_refptr<MyFoo> a = new MyFoo(); | |
| 260 // scoped_refptr<MyFoo> b; | |
| 261 // | |
| 262 // b = a; | |
| 263 // // now, |a| and |b| each own a reference to the same MyFoo object. | |
| 264 // } | |
| 265 // | |
| 266 template <class T> | |
| 267 class scoped_refptr { | |
| 268 TYPE_WITH_MOVE_CONSTRUCTOR_FOR_CPP_03(scoped_refptr) | |
| 269 public: | |
| 270 typedef T element_type; | |
| 271 | |
| 272 scoped_refptr() : ptr_(NULL) { | |
| 273 } | |
| 274 | |
| 275 scoped_refptr(T* p) : ptr_(p) { | |
| 276 if (ptr_) | |
| 277 AddRef(ptr_); | |
| 278 } | |
| 279 | |
| 280 scoped_refptr(const scoped_refptr<T>& r) : ptr_(r.ptr_) { | |
| 281 if (ptr_) | |
| 282 AddRef(ptr_); | |
| 283 } | |
| 284 | |
| 285 template <typename U> | |
| 286 scoped_refptr(const scoped_refptr<U>& r) : ptr_(r.get()) { | |
| 287 if (ptr_) | |
| 288 AddRef(ptr_); | |
| 289 } | |
| 290 | |
| 291 template <typename U> | |
| 292 scoped_refptr(scoped_refptr<U>&& r) : ptr_(r.get()) { | |
| 293 r.ptr_ = nullptr; | |
| 294 } | |
| 295 | |
| 296 ~scoped_refptr() { | |
| 297 if (ptr_) | |
| 298 Release(ptr_); | |
| 299 } | |
| 300 | |
| 301 T* get() const { return ptr_; } | |
| 302 | |
| 303 T& operator*() const { | |
| 304 assert(ptr_ != NULL); | |
| 305 return *ptr_; | |
| 306 } | |
| 307 | |
| 308 T* operator->() const { | |
| 309 assert(ptr_ != NULL); | |
| 310 return ptr_; | |
| 311 } | |
| 312 | |
| 313 scoped_refptr<T>& operator=(T* p) { | |
| 314 // AddRef first so that self assignment should work | |
| 315 if (p) | |
| 316 AddRef(p); | |
| 317 T* old_ptr = ptr_; | |
| 318 ptr_ = p; | |
| 319 if (old_ptr) | |
| 320 Release(old_ptr); | |
| 321 return *this; | |
| 322 } | |
| 323 | |
| 324 scoped_refptr<T>& operator=(const scoped_refptr<T>& r) { | |
| 325 return *this = r.ptr_; | |
| 326 } | |
| 327 | |
| 328 template <typename U> | |
| 329 scoped_refptr<T>& operator=(const scoped_refptr<U>& r) { | |
| 330 return *this = r.get(); | |
| 331 } | |
| 332 | |
| 333 scoped_refptr<T>& operator=(scoped_refptr<T>&& r) { | |
| 334 scoped_refptr<T>(r.Pass()).swap(*this); | |
| 335 return *this; | |
| 336 } | |
| 337 | |
| 338 template <typename U> | |
| 339 scoped_refptr<T>& operator=(scoped_refptr<U>&& r) { | |
| 340 scoped_refptr<T>(r.Pass()).swap(*this); | |
| 341 return *this; | |
| 342 } | |
| 343 | |
| 344 void swap(T** pp) { | |
| 345 T* p = ptr_; | |
| 346 ptr_ = *pp; | |
| 347 *pp = p; | |
| 348 } | |
| 349 | |
| 350 void swap(scoped_refptr<T>& r) { | |
| 351 swap(&r.ptr_); | |
| 352 } | |
| 353 | |
| 354 private: | |
| 355 template <typename U> friend class scoped_refptr; | |
| 356 | |
| 357 // Allow scoped_refptr<T> to be used in boolean expressions, but not | |
| 358 // implicitly convertible to a real bool (which is dangerous). | |
| 359 // | |
| 360 // Note that this trick is only safe when the == and != operators | |
| 361 // are declared explicitly, as otherwise "refptr1 == refptr2" | |
| 362 // will compile but do the wrong thing (i.e., convert to Testable | |
| 363 // and then do the comparison). | |
| 364 typedef T* scoped_refptr::*Testable; | |
| 365 | |
| 366 public: | |
| 367 operator Testable() const { return ptr_ ? &scoped_refptr::ptr_ : nullptr; } | |
| 368 | |
| 369 template <typename U> | |
| 370 bool operator==(const scoped_refptr<U>& rhs) const { | |
| 371 return ptr_ == rhs.get(); | |
| 372 } | |
| 373 | |
| 374 template <typename U> | |
| 375 bool operator!=(const scoped_refptr<U>& rhs) const { | |
| 376 return !operator==(rhs); | |
| 377 } | |
| 378 | |
| 379 template <typename U> | |
| 380 bool operator<(const scoped_refptr<U>& rhs) const { | |
| 381 return ptr_ < rhs.get(); | |
| 382 } | |
| 383 | |
| 384 protected: | |
| 385 T* ptr_; | |
| 386 | |
| 387 private: | |
| 388 // Non-inline helpers to allow: | |
| 389 // class Opaque; | |
| 390 // extern template class scoped_refptr<Opaque>; | |
| 391 // Otherwise the compiler will complain that Opaque is an incomplete type. | |
| 392 static void AddRef(T* ptr); | |
| 393 static void Release(T* ptr); | |
| 394 }; | |
| 395 | |
| 396 template <typename T> | |
| 397 void scoped_refptr<T>::AddRef(T* ptr) { | |
| 398 ptr->AddRef(); | |
| 399 } | |
| 400 | |
| 401 template <typename T> | |
| 402 void scoped_refptr<T>::Release(T* ptr) { | |
| 403 ptr->Release(); | |
| 404 } | |
| 405 | |
| 406 // Handy utility for creating a scoped_refptr<T> out of a T* explicitly without | |
| 407 // having to retype all the template arguments | |
| 408 template <typename T> | |
| 409 scoped_refptr<T> make_scoped_refptr(T* t) { | |
| 410 return scoped_refptr<T>(t); | |
| 411 } | |
| 412 | |
| 413 // Temporary operator overloads to facilitate the transition. See | |
| 414 // https://crbug.com/110610. | |
| 415 template <typename T, typename U> | |
| 416 bool operator==(const scoped_refptr<T>& lhs, const U* rhs) { | |
| 417 return lhs.get() == rhs; | |
| 418 } | |
| 419 | |
| 420 template <typename T, typename U> | |
| 421 bool operator==(const T* lhs, const scoped_refptr<U>& rhs) { | |
| 422 return lhs == rhs.get(); | |
| 423 } | |
| 424 | |
| 425 template <typename T, typename U> | |
| 426 bool operator!=(const scoped_refptr<T>& lhs, const U* rhs) { | |
| 427 return !operator==(lhs, rhs); | |
| 428 } | |
| 429 | |
| 430 template <typename T, typename U> | |
| 431 bool operator!=(const T* lhs, const scoped_refptr<U>& rhs) { | |
| 432 return !operator==(lhs, rhs); | |
| 433 } | |
| 434 | |
| 435 template <typename T> | |
| 436 std::ostream& operator<<(std::ostream& out, const scoped_refptr<T>& p) { | |
| 437 return out << p.get(); | |
| 438 } | |
| 439 | |
| 440 #endif // BASE_MEMORY_REF_COUNTED_H_ | |
| OLD | NEW |