Home | History | Annotate | Download | only in wtf
      1 /*
      2  * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
      3  *
      4  * This library is free software; you can redistribute it and/or
      5  * modify it under the terms of the GNU Library General Public
      6  * License as published by the Free Software Foundation; either
      7  * version 2 of the License, or (at your option) any later version.
      8  *
      9  * This library is distributed in the hope that it will be useful,
     10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     12  * Library General Public License for more details.
     13  *
     14  * You should have received a copy of the GNU Library General Public License
     15  * along with this library; see the file COPYING.LIB.  If not, write to
     16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     17  * Boston, MA 02110-1301, USA.
     18  *
     19  */
     20 
     21 #ifndef RefCounted_h
     22 #define RefCounted_h
     23 
     24 #include <wtf/Assertions.h>
     25 #include <wtf/Noncopyable.h>
     26 
     27 namespace WTF {
     28 
     29 // This base class holds the non-template methods and attributes.
     30 // The RefCounted class inherits from it reducing the template bloat
     31 // generated by the compiler (technique called template hoisting).
     32 class RefCountedBase {
     33 public:
     34     void ref()
     35     {
     36         ASSERT(!m_deletionHasBegun);
     37         ++m_refCount;
     38     }
     39 
     40     bool hasOneRef() const
     41     {
     42         ASSERT(!m_deletionHasBegun);
     43         return m_refCount == 1;
     44     }
     45 
     46     int refCount() const
     47     {
     48         return m_refCount;
     49     }
     50 
     51 protected:
     52     RefCountedBase()
     53         : m_refCount(1)
     54 #ifndef NDEBUG
     55         , m_deletionHasBegun(false)
     56 #endif
     57     {
     58     }
     59 
     60     ~RefCountedBase()
     61     {
     62     }
     63 
     64     // Returns whether the pointer should be freed or not.
     65     bool derefBase()
     66     {
     67         ASSERT(!m_deletionHasBegun);
     68         ASSERT(m_refCount > 0);
     69         if (m_refCount == 1) {
     70 #ifndef NDEBUG
     71             m_deletionHasBegun = true;
     72 #endif
     73             return true;
     74         }
     75 
     76         --m_refCount;
     77         return false;
     78     }
     79 
     80     // Helper for generating JIT code. Please do not use for non-JIT purposes.
     81     int* addressOfCount()
     82     {
     83         return &m_refCount;
     84     }
     85 
     86 #ifndef NDEBUG
     87     bool deletionHasBegun() const
     88     {
     89         return m_deletionHasBegun;
     90     }
     91 #endif
     92 
     93 private:
     94     template<class T>
     95     friend class CrossThreadRefCounted;
     96 
     97     int m_refCount;
     98 #ifndef NDEBUG
     99     bool m_deletionHasBegun;
    100 #endif
    101 };
    102 
    103 
    104 template<class T> class RefCounted : public RefCountedBase, public Noncopyable {
    105 public:
    106     void deref()
    107     {
    108         if (derefBase())
    109             delete static_cast<T*>(this);
    110     }
    111 
    112 protected:
    113     ~RefCounted()
    114     {
    115     }
    116 };
    117 
    118 template<class T> class RefCountedCustomAllocated : public RefCountedBase, public NoncopyableCustomAllocated {
    119 public:
    120     void deref()
    121     {
    122         if (derefBase())
    123             delete static_cast<T*>(this);
    124     }
    125 
    126 protected:
    127     ~RefCountedCustomAllocated()
    128     {
    129     }
    130 };
    131 
    132 } // namespace WTF
    133 
    134 using WTF::RefCounted;
    135 using WTF::RefCountedCustomAllocated;
    136 
    137 #endif // RefCounted_h
    138