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

Wed, 31 Dec 2014 07:16:47 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:16:47 +0100
branch
TOR_BUG_9701
changeset 3
141e0f1194b1
permissions
-rw-r--r--

Revert simplistic fix pending revisit of Mozilla integration attempt.

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

mercurial