security/sandbox/chromium/base/memory/ref_counted.h

Wed, 31 Dec 2014 06:55:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:50 +0100
changeset 2
7e26c7da4463
permissions
-rw-r--r--

Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2

michael@0 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
michael@0 2 // Use of this source code is governed by a BSD-style license that can be
michael@0 3 // found in the LICENSE file.
michael@0 4
michael@0 5 #ifndef BASE_MEMORY_REF_COUNTED_H_
michael@0 6 #define BASE_MEMORY_REF_COUNTED_H_
michael@0 7
michael@0 8 #include <cassert>
michael@0 9
michael@0 10 #include "base/atomic_ref_count.h"
michael@0 11 #include "base/base_export.h"
michael@0 12 #include "base/compiler_specific.h"
michael@0 13 #include "base/threading/thread_collision_warner.h"
michael@0 14
michael@0 15 namespace base {
michael@0 16
michael@0 17 namespace subtle {
michael@0 18
michael@0 19 class BASE_EXPORT RefCountedBase {
michael@0 20 public:
michael@0 21 bool HasOneRef() const { return ref_count_ == 1; }
michael@0 22
michael@0 23 protected:
michael@0 24 RefCountedBase();
michael@0 25 ~RefCountedBase();
michael@0 26
michael@0 27 void AddRef() const;
michael@0 28
michael@0 29 // Returns true if the object should self-delete.
michael@0 30 bool Release() const;
michael@0 31
michael@0 32 private:
michael@0 33 mutable int ref_count_;
michael@0 34 #ifndef NDEBUG
michael@0 35 mutable bool in_dtor_;
michael@0 36 #endif
michael@0 37
michael@0 38 DFAKE_MUTEX(add_release_);
michael@0 39
michael@0 40 DISALLOW_COPY_AND_ASSIGN(RefCountedBase);
michael@0 41 };
michael@0 42
michael@0 43 class BASE_EXPORT RefCountedThreadSafeBase {
michael@0 44 public:
michael@0 45 bool HasOneRef() const;
michael@0 46
michael@0 47 protected:
michael@0 48 RefCountedThreadSafeBase();
michael@0 49 ~RefCountedThreadSafeBase();
michael@0 50
michael@0 51 void AddRef() const;
michael@0 52
michael@0 53 // Returns true if the object should self-delete.
michael@0 54 bool Release() const;
michael@0 55
michael@0 56 private:
michael@0 57 mutable AtomicRefCount ref_count_;
michael@0 58 #ifndef NDEBUG
michael@0 59 mutable bool in_dtor_;
michael@0 60 #endif
michael@0 61
michael@0 62 DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafeBase);
michael@0 63 };
michael@0 64
michael@0 65 } // namespace subtle
michael@0 66
michael@0 67 //
michael@0 68 // A base class for reference counted classes. Otherwise, known as a cheap
michael@0 69 // knock-off of WebKit's RefCounted<T> class. To use this guy just extend your
michael@0 70 // class from it like so:
michael@0 71 //
michael@0 72 // class MyFoo : public base::RefCounted<MyFoo> {
michael@0 73 // ...
michael@0 74 // private:
michael@0 75 // friend class base::RefCounted<MyFoo>;
michael@0 76 // ~MyFoo();
michael@0 77 // };
michael@0 78 //
michael@0 79 // You should always make your destructor private, to avoid any code deleting
michael@0 80 // the object accidently while there are references to it.
michael@0 81 template <class T>
michael@0 82 class RefCounted : public subtle::RefCountedBase {
michael@0 83 public:
michael@0 84 RefCounted() {}
michael@0 85
michael@0 86 void AddRef() const {
michael@0 87 subtle::RefCountedBase::AddRef();
michael@0 88 }
michael@0 89
michael@0 90 void Release() const {
michael@0 91 if (subtle::RefCountedBase::Release()) {
michael@0 92 delete static_cast<const T*>(this);
michael@0 93 }
michael@0 94 }
michael@0 95
michael@0 96 protected:
michael@0 97 ~RefCounted() {}
michael@0 98
michael@0 99 private:
michael@0 100 DISALLOW_COPY_AND_ASSIGN(RefCounted<T>);
michael@0 101 };
michael@0 102
michael@0 103 // Forward declaration.
michael@0 104 template <class T, typename Traits> class RefCountedThreadSafe;
michael@0 105
michael@0 106 // Default traits for RefCountedThreadSafe<T>. Deletes the object when its ref
michael@0 107 // count reaches 0. Overload to delete it on a different thread etc.
michael@0 108 template<typename T>
michael@0 109 struct DefaultRefCountedThreadSafeTraits {
michael@0 110 static void Destruct(const T* x) {
michael@0 111 // Delete through RefCountedThreadSafe to make child classes only need to be
michael@0 112 // friend with RefCountedThreadSafe instead of this struct, which is an
michael@0 113 // implementation detail.
michael@0 114 RefCountedThreadSafe<T,
michael@0 115 DefaultRefCountedThreadSafeTraits>::DeleteInternal(x);
michael@0 116 }
michael@0 117 };
michael@0 118
michael@0 119 //
michael@0 120 // A thread-safe variant of RefCounted<T>
michael@0 121 //
michael@0 122 // class MyFoo : public base::RefCountedThreadSafe<MyFoo> {
michael@0 123 // ...
michael@0 124 // };
michael@0 125 //
michael@0 126 // If you're using the default trait, then you should add compile time
michael@0 127 // asserts that no one else is deleting your object. i.e.
michael@0 128 // private:
michael@0 129 // friend class base::RefCountedThreadSafe<MyFoo>;
michael@0 130 // ~MyFoo();
michael@0 131 template <class T, typename Traits = DefaultRefCountedThreadSafeTraits<T> >
michael@0 132 class RefCountedThreadSafe : public subtle::RefCountedThreadSafeBase {
michael@0 133 public:
michael@0 134 RefCountedThreadSafe() {}
michael@0 135
michael@0 136 void AddRef() const {
michael@0 137 subtle::RefCountedThreadSafeBase::AddRef();
michael@0 138 }
michael@0 139
michael@0 140 void Release() const {
michael@0 141 if (subtle::RefCountedThreadSafeBase::Release()) {
michael@0 142 Traits::Destruct(static_cast<const T*>(this));
michael@0 143 }
michael@0 144 }
michael@0 145
michael@0 146 protected:
michael@0 147 ~RefCountedThreadSafe() {}
michael@0 148
michael@0 149 private:
michael@0 150 friend struct DefaultRefCountedThreadSafeTraits<T>;
michael@0 151 static void DeleteInternal(const T* x) { delete x; }
michael@0 152
michael@0 153 DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafe);
michael@0 154 };
michael@0 155
michael@0 156 //
michael@0 157 // A thread-safe wrapper for some piece of data so we can place other
michael@0 158 // things in scoped_refptrs<>.
michael@0 159 //
michael@0 160 template<typename T>
michael@0 161 class RefCountedData
michael@0 162 : public base::RefCountedThreadSafe< base::RefCountedData<T> > {
michael@0 163 public:
michael@0 164 RefCountedData() : data() {}
michael@0 165 RefCountedData(const T& in_value) : data(in_value) {}
michael@0 166
michael@0 167 T data;
michael@0 168
michael@0 169 private:
michael@0 170 friend class base::RefCountedThreadSafe<base::RefCountedData<T> >;
michael@0 171 ~RefCountedData() {}
michael@0 172 };
michael@0 173
michael@0 174 } // namespace base
michael@0 175
michael@0 176 //
michael@0 177 // A smart pointer class for reference counted objects. Use this class instead
michael@0 178 // of calling AddRef and Release manually on a reference counted object to
michael@0 179 // avoid common memory leaks caused by forgetting to Release an object
michael@0 180 // reference. Sample usage:
michael@0 181 //
michael@0 182 // class MyFoo : public RefCounted<MyFoo> {
michael@0 183 // ...
michael@0 184 // };
michael@0 185 //
michael@0 186 // void some_function() {
michael@0 187 // scoped_refptr<MyFoo> foo = new MyFoo();
michael@0 188 // foo->Method(param);
michael@0 189 // // |foo| is released when this function returns
michael@0 190 // }
michael@0 191 //
michael@0 192 // void some_other_function() {
michael@0 193 // scoped_refptr<MyFoo> foo = new MyFoo();
michael@0 194 // ...
michael@0 195 // foo = NULL; // explicitly releases |foo|
michael@0 196 // ...
michael@0 197 // if (foo)
michael@0 198 // foo->Method(param);
michael@0 199 // }
michael@0 200 //
michael@0 201 // The above examples show how scoped_refptr<T> acts like a pointer to T.
michael@0 202 // Given two scoped_refptr<T> classes, it is also possible to exchange
michael@0 203 // references between the two objects, like so:
michael@0 204 //
michael@0 205 // {
michael@0 206 // scoped_refptr<MyFoo> a = new MyFoo();
michael@0 207 // scoped_refptr<MyFoo> b;
michael@0 208 //
michael@0 209 // b.swap(a);
michael@0 210 // // now, |b| references the MyFoo object, and |a| references NULL.
michael@0 211 // }
michael@0 212 //
michael@0 213 // To make both |a| and |b| in the above example reference the same MyFoo
michael@0 214 // object, simply use the assignment operator:
michael@0 215 //
michael@0 216 // {
michael@0 217 // scoped_refptr<MyFoo> a = new MyFoo();
michael@0 218 // scoped_refptr<MyFoo> b;
michael@0 219 //
michael@0 220 // b = a;
michael@0 221 // // now, |a| and |b| each own a reference to the same MyFoo object.
michael@0 222 // }
michael@0 223 //
michael@0 224 template <class T>
michael@0 225 class scoped_refptr {
michael@0 226 public:
michael@0 227 typedef T element_type;
michael@0 228
michael@0 229 scoped_refptr() : ptr_(NULL) {
michael@0 230 }
michael@0 231
michael@0 232 scoped_refptr(T* p) : ptr_(p) {
michael@0 233 if (ptr_)
michael@0 234 ptr_->AddRef();
michael@0 235 }
michael@0 236
michael@0 237 scoped_refptr(const scoped_refptr<T>& r) : ptr_(r.ptr_) {
michael@0 238 if (ptr_)
michael@0 239 ptr_->AddRef();
michael@0 240 }
michael@0 241
michael@0 242 template <typename U>
michael@0 243 scoped_refptr(const scoped_refptr<U>& r) : ptr_(r.get()) {
michael@0 244 if (ptr_)
michael@0 245 ptr_->AddRef();
michael@0 246 }
michael@0 247
michael@0 248 ~scoped_refptr() {
michael@0 249 if (ptr_)
michael@0 250 ptr_->Release();
michael@0 251 }
michael@0 252
michael@0 253 T* get() const { return ptr_; }
michael@0 254 operator T*() const { return ptr_; }
michael@0 255 T* operator->() const {
michael@0 256 assert(ptr_ != NULL);
michael@0 257 return ptr_;
michael@0 258 }
michael@0 259
michael@0 260 scoped_refptr<T>& operator=(T* p) {
michael@0 261 // AddRef first so that self assignment should work
michael@0 262 if (p)
michael@0 263 p->AddRef();
michael@0 264 T* old_ptr = ptr_;
michael@0 265 ptr_ = p;
michael@0 266 if (old_ptr)
michael@0 267 old_ptr->Release();
michael@0 268 return *this;
michael@0 269 }
michael@0 270
michael@0 271 scoped_refptr<T>& operator=(const scoped_refptr<T>& r) {
michael@0 272 return *this = r.ptr_;
michael@0 273 }
michael@0 274
michael@0 275 template <typename U>
michael@0 276 scoped_refptr<T>& operator=(const scoped_refptr<U>& r) {
michael@0 277 return *this = r.get();
michael@0 278 }
michael@0 279
michael@0 280 void swap(T** pp) {
michael@0 281 T* p = ptr_;
michael@0 282 ptr_ = *pp;
michael@0 283 *pp = p;
michael@0 284 }
michael@0 285
michael@0 286 void swap(scoped_refptr<T>& r) {
michael@0 287 swap(&r.ptr_);
michael@0 288 }
michael@0 289
michael@0 290 protected:
michael@0 291 T* ptr_;
michael@0 292 };
michael@0 293
michael@0 294 // Handy utility for creating a scoped_refptr<T> out of a T* explicitly without
michael@0 295 // having to retype all the template arguments
michael@0 296 template <typename T>
michael@0 297 scoped_refptr<T> make_scoped_refptr(T* t) {
michael@0 298 return scoped_refptr<T>(t);
michael@0 299 }
michael@0 300
michael@0 301 #endif // BASE_MEMORY_REF_COUNTED_H_

mercurial