ipc/chromium/src/base/ref_counted.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 // Copyright (c) 2006-2008 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.
     5 #ifndef BASE_REF_COUNTED_H_
     6 #define BASE_REF_COUNTED_H_
     8 #include "base/atomic_ref_count.h"
     9 #include "base/thread_collision_warner.h"
    11 namespace base {
    13 namespace subtle {
    15 class RefCountedBase {
    16  protected:
    17   RefCountedBase();
    18   ~RefCountedBase();
    20   void AddRef();
    22   // Returns true if the object should self-delete.
    23   bool Release();
    25  private:
    26   int ref_count_;
    27 #ifndef NDEBUG
    28   bool in_dtor_;
    29 #endif
    31   DFAKE_MUTEX(add_release_)
    33   DISALLOW_COPY_AND_ASSIGN(RefCountedBase);
    34 };
    36 class RefCountedThreadSafeBase {
    37  protected:
    38   RefCountedThreadSafeBase();
    39   ~RefCountedThreadSafeBase();
    41   void AddRef();
    43   // Returns true if the object should self-delete.
    44   bool Release();
    46  private:
    47   AtomicRefCount ref_count_;
    48 #ifndef NDEBUG
    49   bool in_dtor_;
    50 #endif
    52   DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafeBase);
    53 };
    57 }  // namespace subtle
    59 //
    60 // A base class for reference counted classes.  Otherwise, known as a cheap
    61 // knock-off of WebKit's RefCounted<T> class.  To use this guy just extend your
    62 // class from it like so:
    63 //
    64 //   class MyFoo : public base::RefCounted<MyFoo> {
    65 //    ...
    66 //   };
    67 //
    68 template <class T>
    69 class RefCounted : public subtle::RefCountedBase {
    70  public:
    71   RefCounted() { }
    72   ~RefCounted() { }
    74   void AddRef() {
    75     subtle::RefCountedBase::AddRef();
    76   }
    78   void Release() {
    79     if (subtle::RefCountedBase::Release()) {
    80       delete static_cast<T*>(this);
    81     }
    82   }
    84  private:
    85   DISALLOW_COPY_AND_ASSIGN(RefCounted<T>);
    86 };
    88 //
    89 // A thread-safe variant of RefCounted<T>
    90 //
    91 //   class MyFoo : public base::RefCountedThreadSafe<MyFoo> {
    92 //    ...
    93 //   };
    94 //
    95 template <class T>
    96 class RefCountedThreadSafe : public subtle::RefCountedThreadSafeBase {
    97  public:
    98   RefCountedThreadSafe() { }
    99   ~RefCountedThreadSafe() { }
   101   void AddRef() {
   102     subtle::RefCountedThreadSafeBase::AddRef();
   103   }
   105   void Release() {
   106     if (subtle::RefCountedThreadSafeBase::Release()) {
   107       delete static_cast<T*>(this);
   108     }
   109   }
   111  private:
   112   DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafe<T>);
   113 };
   115 //
   116 // A wrapper for some piece of data so we can place other things in
   117 // scoped_refptrs<>.
   118 //
   119 template<typename T>
   120 class RefCountedData : public base::RefCounted< base::RefCountedData<T> > {
   121  public:
   122   RefCountedData() : data() {}
   123   RefCountedData(const T& in_value) : data(in_value) {}
   125   T data;
   126 };
   128 }  // namespace base
   130 //
   131 // A smart pointer class for reference counted objects.  Use this class instead
   132 // of calling AddRef and Release manually on a reference counted object to
   133 // avoid common memory leaks caused by forgetting to Release an object
   134 // reference.  Sample usage:
   135 //
   136 //   class MyFoo : public RefCounted<MyFoo> {
   137 //    ...
   138 //   };
   139 //
   140 //   void some_function() {
   141 //     scoped_refptr<MyFoo> foo = new MyFoo();
   142 //     foo->Method(param);
   143 //     // |foo| is released when this function returns
   144 //   }
   145 //
   146 //   void some_other_function() {
   147 //     scoped_refptr<MyFoo> foo = new MyFoo();
   148 //     ...
   149 //     foo = NULL;  // explicitly releases |foo|
   150 //     ...
   151 //     if (foo)
   152 //       foo->Method(param);
   153 //   }
   154 //
   155 // The above examples show how scoped_refptr<T> acts like a pointer to T.
   156 // Given two scoped_refptr<T> classes, it is also possible to exchange
   157 // references between the two objects, like so:
   158 //
   159 //   {
   160 //     scoped_refptr<MyFoo> a = new MyFoo();
   161 //     scoped_refptr<MyFoo> b;
   162 //
   163 //     b.swap(a);
   164 //     // now, |b| references the MyFoo object, and |a| references NULL.
   165 //   }
   166 //
   167 // To make both |a| and |b| in the above example reference the same MyFoo
   168 // object, simply use the assignment operator:
   169 //
   170 //   {
   171 //     scoped_refptr<MyFoo> a = new MyFoo();
   172 //     scoped_refptr<MyFoo> b;
   173 //
   174 //     b = a;
   175 //     // now, |a| and |b| each own a reference to the same MyFoo object.
   176 //   }
   177 //
   178 template <class T>
   179 class scoped_refptr {
   180  public:
   181   scoped_refptr() : ptr_(NULL) {
   182   }
   184   scoped_refptr(T* p) : ptr_(p) {
   185     if (ptr_)
   186       ptr_->AddRef();
   187   }
   189   scoped_refptr(const scoped_refptr<T>& r) : ptr_(r.ptr_) {
   190     if (ptr_)
   191       ptr_->AddRef();
   192   }
   194   ~scoped_refptr() {
   195     if (ptr_)
   196       ptr_->Release();
   197   }
   199   T* get() const { return ptr_; }
   200   operator T*() const { return ptr_; }
   201   T* operator->() const { return ptr_; }
   203   scoped_refptr<T>& operator=(T* p) {
   204     // AddRef first so that self assignment should work
   205     if (p)
   206       p->AddRef();
   207     if (ptr_ )
   208       ptr_ ->Release();
   209     ptr_ = p;
   210     return *this;
   211   }
   213   scoped_refptr<T>& operator=(const scoped_refptr<T>& r) {
   214     return *this = r.ptr_;
   215   }
   217   void swap(T** pp) {
   218     T* p = ptr_;
   219     ptr_ = *pp;
   220     *pp = p;
   221   }
   223   void swap(scoped_refptr<T>& r) {
   224     swap(&r.ptr_);
   225   }
   227  protected:
   228   T* ptr_;
   229 };
   231 #endif  // BASE_REF_COUNTED_H_

mercurial