LCOV - code coverage report
Current view: directory - ipc/chromium/src/base - ref_counted.h (source / functions) Found Hit Coverage
Test: app.info Lines: 44 32 72.7 %
Date: 2012-06-02 Functions: 90 23 25.6 %

       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.
       4                 : 
       5                 : #ifndef BASE_REF_COUNTED_H_
       6                 : #define BASE_REF_COUNTED_H_
       7                 : 
       8                 : #include "base/atomic_ref_count.h"
       9                 : #include "base/thread_collision_warner.h"
      10                 : 
      11                 : namespace base {
      12                 : 
      13                 : namespace subtle {
      14                 : 
      15                 : class RefCountedBase {
      16                 :  protected:
      17                 :   RefCountedBase();
      18                 :   ~RefCountedBase();
      19                 : 
      20                 :   void AddRef();
      21                 : 
      22                 :   // Returns true if the object should self-delete.
      23                 :   bool Release();
      24                 : 
      25                 :  private:
      26                 :   int ref_count_;
      27                 : #ifndef NDEBUG
      28                 :   bool in_dtor_;
      29                 : #endif
      30                 : 
      31                 :   DFAKE_MUTEX(add_release_);
      32                 : 
      33                 :   DISALLOW_COPY_AND_ASSIGN(RefCountedBase);
      34                 : };
      35                 : 
      36                 : class RefCountedThreadSafeBase {
      37                 :  protected:
      38                 :   RefCountedThreadSafeBase();
      39                 :   ~RefCountedThreadSafeBase();
      40                 : 
      41                 :   void AddRef();
      42                 : 
      43                 :   // Returns true if the object should self-delete.
      44                 :   bool Release();
      45                 : 
      46                 :  private:
      47                 :   AtomicRefCount ref_count_;
      48                 : #ifndef NDEBUG
      49                 :   bool in_dtor_;
      50                 : #endif
      51                 : 
      52                 :   DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafeBase);
      53                 : };
      54                 : 
      55                 : 
      56                 : 
      57                 : }  // namespace subtle
      58                 : 
      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               1 :   RefCounted() { }
      72               0 :   ~RefCounted() { }
      73                 : 
      74               1 :   void AddRef() {
      75               1 :     subtle::RefCountedBase::AddRef();
      76               1 :   }
      77                 : 
      78               0 :   void Release() {
      79               0 :     if (subtle::RefCountedBase::Release()) {
      80               0 :       delete static_cast<T*>(this);
      81                 :     }
      82               0 :   }
      83                 : 
      84                 :  private:
      85                 :   DISALLOW_COPY_AND_ASSIGN(RefCounted<T>);
      86                 : };
      87                 : 
      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            7145 :   RefCountedThreadSafe() { }
      99            5677 :   ~RefCountedThreadSafe() { }
     100                 : 
     101            8564 :   void AddRef() {
     102            8564 :     subtle::RefCountedThreadSafeBase::AddRef();
     103            8564 :   }
     104                 : 
     105            7096 :   void Release() {
     106            7096 :     if (subtle::RefCountedThreadSafeBase::Release()) {
     107            5677 :       delete static_cast<T*>(this);
     108                 :     }
     109            7096 :   }
     110                 : 
     111                 :  private:
     112                 :   DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafe<T>);
     113                 : };
     114                 : 
     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) {}
     124                 : 
     125                 :   T data;
     126                 : };
     127                 : 
     128                 : }  // namespace base
     129                 : 
     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            4263 :   scoped_refptr() : ptr_(NULL) {
     182            4263 :   }
     183                 : 
     184            4306 :   scoped_refptr(T* p) : ptr_(p) {
     185            4306 :     if (ptr_)
     186            4305 :       ptr_->AddRef();
     187            4306 :   }
     188                 : 
     189               0 :   scoped_refptr(const scoped_refptr<T>& r) : ptr_(r.ptr_) {
     190               0 :     if (ptr_)
     191               0 :       ptr_->AddRef();
     192               0 :   }
     193                 : 
     194            7096 :   ~scoped_refptr() {
     195            7096 :     if (ptr_)
     196            7096 :       ptr_->Release();
     197            7096 :   }
     198                 : 
     199               0 :   T* get() const { return ptr_; }
     200               0 :   operator T*() const { return ptr_; }
     201           22712 :   T* operator->() const { return ptr_; }
     202                 : 
     203            4260 :   scoped_refptr<T>& operator=(T* p) {
     204                 :     // AddRef first so that self assignment should work
     205            4260 :     if (p)
     206            4260 :       p->AddRef();
     207            4260 :     if (ptr_ )
     208               0 :       ptr_ ->Release();
     209            4260 :     ptr_ = p;
     210            4260 :     return *this;
     211                 :   }
     212                 : 
     213            1419 :   scoped_refptr<T>& operator=(const scoped_refptr<T>& r) {
     214            1419 :     return *this = r.ptr_;
     215                 :   }
     216                 : 
     217                 :   void swap(T** pp) {
     218                 :     T* p = ptr_;
     219                 :     ptr_ = *pp;
     220                 :     *pp = p;
     221                 :   }
     222                 : 
     223                 :   void swap(scoped_refptr<T>& r) {
     224                 :     swap(&r.ptr_);
     225                 :   }
     226                 : 
     227                 :  protected:
     228                 :   T* ptr_;
     229                 : };
     230                 : 
     231                 : #endif  // BASE_REF_COUNTED_H_

Generated by: LCOV version 1.7