ipc/chromium/src/base/ref_counted.h

changeset 0
6474c204b198
     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_

mercurial