1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/ipc/chromium/src/base/ref_counted.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,231 @@ 1.4 +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1.5 +// Use of this source code is governed by a BSD-style license that can be 1.6 +// found in the LICENSE file. 1.7 + 1.8 +#ifndef BASE_REF_COUNTED_H_ 1.9 +#define BASE_REF_COUNTED_H_ 1.10 + 1.11 +#include "base/atomic_ref_count.h" 1.12 +#include "base/thread_collision_warner.h" 1.13 + 1.14 +namespace base { 1.15 + 1.16 +namespace subtle { 1.17 + 1.18 +class RefCountedBase { 1.19 + protected: 1.20 + RefCountedBase(); 1.21 + ~RefCountedBase(); 1.22 + 1.23 + void AddRef(); 1.24 + 1.25 + // Returns true if the object should self-delete. 1.26 + bool Release(); 1.27 + 1.28 + private: 1.29 + int ref_count_; 1.30 +#ifndef NDEBUG 1.31 + bool in_dtor_; 1.32 +#endif 1.33 + 1.34 + DFAKE_MUTEX(add_release_) 1.35 + 1.36 + DISALLOW_COPY_AND_ASSIGN(RefCountedBase); 1.37 +}; 1.38 + 1.39 +class RefCountedThreadSafeBase { 1.40 + protected: 1.41 + RefCountedThreadSafeBase(); 1.42 + ~RefCountedThreadSafeBase(); 1.43 + 1.44 + void AddRef(); 1.45 + 1.46 + // Returns true if the object should self-delete. 1.47 + bool Release(); 1.48 + 1.49 + private: 1.50 + AtomicRefCount ref_count_; 1.51 +#ifndef NDEBUG 1.52 + bool in_dtor_; 1.53 +#endif 1.54 + 1.55 + DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafeBase); 1.56 +}; 1.57 + 1.58 + 1.59 + 1.60 +} // namespace subtle 1.61 + 1.62 +// 1.63 +// A base class for reference counted classes. Otherwise, known as a cheap 1.64 +// knock-off of WebKit's RefCounted<T> class. To use this guy just extend your 1.65 +// class from it like so: 1.66 +// 1.67 +// class MyFoo : public base::RefCounted<MyFoo> { 1.68 +// ... 1.69 +// }; 1.70 +// 1.71 +template <class T> 1.72 +class RefCounted : public subtle::RefCountedBase { 1.73 + public: 1.74 + RefCounted() { } 1.75 + ~RefCounted() { } 1.76 + 1.77 + void AddRef() { 1.78 + subtle::RefCountedBase::AddRef(); 1.79 + } 1.80 + 1.81 + void Release() { 1.82 + if (subtle::RefCountedBase::Release()) { 1.83 + delete static_cast<T*>(this); 1.84 + } 1.85 + } 1.86 + 1.87 + private: 1.88 + DISALLOW_COPY_AND_ASSIGN(RefCounted<T>); 1.89 +}; 1.90 + 1.91 +// 1.92 +// A thread-safe variant of RefCounted<T> 1.93 +// 1.94 +// class MyFoo : public base::RefCountedThreadSafe<MyFoo> { 1.95 +// ... 1.96 +// }; 1.97 +// 1.98 +template <class T> 1.99 +class RefCountedThreadSafe : public subtle::RefCountedThreadSafeBase { 1.100 + public: 1.101 + RefCountedThreadSafe() { } 1.102 + ~RefCountedThreadSafe() { } 1.103 + 1.104 + void AddRef() { 1.105 + subtle::RefCountedThreadSafeBase::AddRef(); 1.106 + } 1.107 + 1.108 + void Release() { 1.109 + if (subtle::RefCountedThreadSafeBase::Release()) { 1.110 + delete static_cast<T*>(this); 1.111 + } 1.112 + } 1.113 + 1.114 + private: 1.115 + DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafe<T>); 1.116 +}; 1.117 + 1.118 +// 1.119 +// A wrapper for some piece of data so we can place other things in 1.120 +// scoped_refptrs<>. 1.121 +// 1.122 +template<typename T> 1.123 +class RefCountedData : public base::RefCounted< base::RefCountedData<T> > { 1.124 + public: 1.125 + RefCountedData() : data() {} 1.126 + RefCountedData(const T& in_value) : data(in_value) {} 1.127 + 1.128 + T data; 1.129 +}; 1.130 + 1.131 +} // namespace base 1.132 + 1.133 +// 1.134 +// A smart pointer class for reference counted objects. Use this class instead 1.135 +// of calling AddRef and Release manually on a reference counted object to 1.136 +// avoid common memory leaks caused by forgetting to Release an object 1.137 +// reference. Sample usage: 1.138 +// 1.139 +// class MyFoo : public RefCounted<MyFoo> { 1.140 +// ... 1.141 +// }; 1.142 +// 1.143 +// void some_function() { 1.144 +// scoped_refptr<MyFoo> foo = new MyFoo(); 1.145 +// foo->Method(param); 1.146 +// // |foo| is released when this function returns 1.147 +// } 1.148 +// 1.149 +// void some_other_function() { 1.150 +// scoped_refptr<MyFoo> foo = new MyFoo(); 1.151 +// ... 1.152 +// foo = NULL; // explicitly releases |foo| 1.153 +// ... 1.154 +// if (foo) 1.155 +// foo->Method(param); 1.156 +// } 1.157 +// 1.158 +// The above examples show how scoped_refptr<T> acts like a pointer to T. 1.159 +// Given two scoped_refptr<T> classes, it is also possible to exchange 1.160 +// references between the two objects, like so: 1.161 +// 1.162 +// { 1.163 +// scoped_refptr<MyFoo> a = new MyFoo(); 1.164 +// scoped_refptr<MyFoo> b; 1.165 +// 1.166 +// b.swap(a); 1.167 +// // now, |b| references the MyFoo object, and |a| references NULL. 1.168 +// } 1.169 +// 1.170 +// To make both |a| and |b| in the above example reference the same MyFoo 1.171 +// object, simply use the assignment operator: 1.172 +// 1.173 +// { 1.174 +// scoped_refptr<MyFoo> a = new MyFoo(); 1.175 +// scoped_refptr<MyFoo> b; 1.176 +// 1.177 +// b = a; 1.178 +// // now, |a| and |b| each own a reference to the same MyFoo object. 1.179 +// } 1.180 +// 1.181 +template <class T> 1.182 +class scoped_refptr { 1.183 + public: 1.184 + scoped_refptr() : ptr_(NULL) { 1.185 + } 1.186 + 1.187 + scoped_refptr(T* p) : ptr_(p) { 1.188 + if (ptr_) 1.189 + ptr_->AddRef(); 1.190 + } 1.191 + 1.192 + scoped_refptr(const scoped_refptr<T>& r) : ptr_(r.ptr_) { 1.193 + if (ptr_) 1.194 + ptr_->AddRef(); 1.195 + } 1.196 + 1.197 + ~scoped_refptr() { 1.198 + if (ptr_) 1.199 + ptr_->Release(); 1.200 + } 1.201 + 1.202 + T* get() const { return ptr_; } 1.203 + operator T*() const { return ptr_; } 1.204 + T* operator->() const { return ptr_; } 1.205 + 1.206 + scoped_refptr<T>& operator=(T* p) { 1.207 + // AddRef first so that self assignment should work 1.208 + if (p) 1.209 + p->AddRef(); 1.210 + if (ptr_ ) 1.211 + ptr_ ->Release(); 1.212 + ptr_ = p; 1.213 + return *this; 1.214 + } 1.215 + 1.216 + scoped_refptr<T>& operator=(const scoped_refptr<T>& r) { 1.217 + return *this = r.ptr_; 1.218 + } 1.219 + 1.220 + void swap(T** pp) { 1.221 + T* p = ptr_; 1.222 + ptr_ = *pp; 1.223 + *pp = p; 1.224 + } 1.225 + 1.226 + void swap(scoped_refptr<T>& r) { 1.227 + swap(&r.ptr_); 1.228 + } 1.229 + 1.230 + protected: 1.231 + T* ptr_; 1.232 +}; 1.233 + 1.234 +#endif // BASE_REF_COUNTED_H_